比较提交
5
次代码提交
22c6cb7890
...
096576d882
| 作者 | SHA1 | 提交日期 | |
|---|---|---|---|
|
|
096576d882 | ||
|
|
efe2df4da3 | ||
|
|
bbe4d9acbf | ||
|
|
c25d2de87e | ||
|
|
c4025083af |
@@ -5,6 +5,8 @@ description: "Load the task and affected-layer guidelines before implementation
|
|||||||
|
|
||||||
# Before Development
|
# Before Development
|
||||||
|
|
||||||
|
On entry or a scope/worktree change, verify official `task.py current --source` in the execution root matches the intended approved task. Correct a mismatch with `task.py start <task>` and read back current/phase before editing. Reuse this verification while unchanged; follow project-governance.md → Active Task And Worktree Alignment for degraded identity and worktree boundaries.
|
||||||
|
|
||||||
1. Read the current PRD and applicable design/implementation notes if not already current in context.
|
1. Read the current PRD and applicable design/implementation notes if not already current in context.
|
||||||
2. Identify the smallest behavior gap, affected files, exclusions and validation commands. Reuse the approved plan rather than writing another checklist.
|
2. Identify the smallest behavior gap, affected files, exclusions and validation commands. Reuse the approved plan rather than writing another checklist.
|
||||||
3. Discover package indexes only when the affected layer is unknown. Read its relevant coding and quality contracts; follow references needed for this change.
|
3. Discover package indexes only when the affected layer is unknown. Read its relevant coding and quality contracts; follow references needed for this change.
|
||||||
|
|||||||
@@ -29,9 +29,9 @@ Use this skill during Phase 1 planning to turn the user's request into clear req
|
|||||||
|
|
||||||
## Preconditions
|
## Preconditions
|
||||||
|
|
||||||
Use this skill only after task-creation consent has been given and the user is ready to enter Trellis planning.
|
Use this skill when the user is ready to plan within an existing task or has approved a genuinely needed new task. Follow project-governance.md → Task Reuse; no new-directory approval is needed merely to refine an existing contract.
|
||||||
|
|
||||||
If no task exists yet, create one:
|
First check the current and directly related existing tasks. Reuse one with matching ownership and acceptance, adding only missing requirements and checks. If none is suitable and creation is authorized, create one:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
TASK_DIR=$(python3 ./.trellis/scripts/task.py create "<short task title>" --description "<one-line summary>" --slug <slug>)
|
TASK_DIR=$(python3 ./.trellis/scripts/task.py create "<short task title>" --description "<one-line summary>" --slug <slug>)
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ description: "Verify the current task diff against its acceptance criteria and a
|
|||||||
|
|
||||||
# Task-Scoped Quality Check
|
# Task-Scoped Quality Check
|
||||||
|
|
||||||
|
Verify the active task and actual validation worktree match the task/diff being checked; run official `task.py current --source` again if scope or cwd changed. Checks from the main checkout do not validate an edited isolated copy. Follow project-governance.md → Active Task And Worktree Alignment; record worktree and candidate separately from deployment and independent review.
|
||||||
|
|
||||||
1. Identify files changed by this task. Git dirty state is evidence, not permission to include other work.
|
1. Identify files changed by this task. Git dirty state is evidence, not permission to include other work.
|
||||||
2. Read acceptance criteria and applicable quality contracts not already loaded. Check the complete task diff, not only the last chunk.
|
2. Read acceptance criteria and applicable quality contracts not already loaded. Check the complete task diff, not only the last chunk.
|
||||||
3. Run the minimum meaningful checks: targeted regressions for behavior changes, relevant syntax/type/build checks for affected layers, and governance/reference checks for rules. Expand for shared contracts and cross-layer risks.
|
3. Run the minimum meaningful checks: targeted regressions for behavior changes, relevant syntax/type/build checks for affected layers, and governance/reference checks for rules. Expand for shared contracts and cross-layer risks.
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ Resume work on the current task — pick up at the right phase/step in `.trellis
|
|||||||
|
|
||||||
## Step 1: Load Current Context
|
## Step 1: Load Current Context
|
||||||
|
|
||||||
|
Run `python3 .trellis/scripts/task.py current --source` from the worktree that will actually be edited. Compare with the intended approved task. If mismatched, use official `task.py start <task>` and read back current before resuming. A previous turn's workflow-state may refer to the old task. Follow project-governance.md → Active Task And Worktree Alignment; do not create a legacy global pointer.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python3 ./.trellis/scripts/get_context.py
|
python3 ./.trellis/scripts/get_context.py
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ description: "Close out an explicitly requested session or completed task with t
|
|||||||
|
|
||||||
# Finish Work
|
# Finish Work
|
||||||
|
|
||||||
|
Before closeout, match the active task to the actual execution worktree and record phase, verification, remaining acceptance and who/what is pending. Follow project-governance.md → Active Task And Worktree Alignment. Official `task.py finish` only clears the session pointer; it is not task completion or archive. Do not silently switch to another business task or treat isolated-worktree notes as integrated changes.
|
||||||
|
|
||||||
1. Compare this task with its acceptance criteria and latest validation evidence. Do not scan unrelated active tasks for cleanup.
|
1. Compare this task with its acceptance criteria and latest validation evidence. Do not scan unrelated active tasks for cleanup.
|
||||||
2. Report implementation, tests, independent review and deployment separately. A completed stage can leave the overall task active; unresolved acceptance must not be checked off.
|
2. Report implementation, tests, independent review and deployment separately. A completed stage can leave the overall task active; unresolved acceptance must not be checked off.
|
||||||
3. Update existing task notes with concise, redacted results and remaining steps. Record a journal only when useful or requested; avoid duplicating stable facts across documents.
|
3. Update existing task notes with concise, redacted results and remaining steps. Record a journal only when useful or requested; avoid duplicating stable facts across documents.
|
||||||
|
|||||||
@@ -6,9 +6,11 @@ description: "Initialize or resume non-trivial work in this Trellis project. Ski
|
|||||||
# Start Session
|
# Start Session
|
||||||
|
|
||||||
1. Classify the request before loading context. Pure consultation and small isolated edits do not need a task or a task-creation question. Preserve risk boundaries in AGENTS.md.
|
1. Classify the request before loading context. Pure consultation and small isolated edits do not need a task or a task-creation question. Preserve risk boundaries in AGENTS.md.
|
||||||
2. For tracked work, obtain current task and status from already supplied context, or run get_context.py when missing or stale. Do not enumerate unrelated journals and historical tasks.
|
2. For tracked work, verify `python3 .trellis/scripts/task.py current --source` from the actual execution worktree when entering or switching scope/worktrees. Match it to the intended task; do not treat a previously injected task as proof. Reuse the result while scope and cwd remain unchanged. Do not enumerate unrelated journals and historical tasks.
|
||||||
3. Read the workflow Phase Index and current step on demand. Read the current PRD, then design and implementation notes if needed. Reuse unchanged material already loaded in this session.
|
3. Read the workflow Phase Index and current step on demand. Read the current PRD, then design and implementation notes if needed. Reuse unchanged material already loaded in this session.
|
||||||
4. With no task, obtain task-creation consent for non-trivial work unless already authorized. With a planning task, complete missing decisions; once its plan is approved, start and execute without asking again. An existing PRD alone is not proof of approval.
|
4. Prefer the current or directly related existing task; add a scoped repair stage rather than creating a directory for every fix. Only seek new-task consent when independently managed work has no suitable owner. Follow project-governance.md → Task Reuse. With a planning task, complete missing decisions; an approved unchanged plan needs no repeat approval.
|
||||||
5. For implementation load trellis-before-dev; for verification load trellis-check. Load spec indexes only for affected layers and follow relevant links, not every guideline.
|
5. For implementation load trellis-before-dev; for verification load trellis-check. Load spec indexes only for affected layers and follow relevant links, not every guideline.
|
||||||
|
|
||||||
The project workflow and task status are authoritative over legacy user-level Trellis skills. Missing optional tools require a supported fallback or a precise limitation report, not repeated permission requests.
|
The project workflow and task status are authoritative over legacy user-level Trellis skills. Missing optional tools require a supported fallback or a precise limitation report, not repeated permission requests.
|
||||||
|
|
||||||
|
For an already approved task, use official `task.py start <task>` on mismatch, then read back current and phase before implementation. Follow `.trellis/spec/hyb-oa/project-governance.md` → Active Task And Worktree Alignment; never create a shared pointer or infer hook delivery from start's success message.
|
||||||
|
|||||||
@@ -22,6 +22,57 @@ tasks after TRELLIS2.
|
|||||||
- Keep edits scoped to the current Trellis task.
|
- Keep edits scoped to the current Trellis task.
|
||||||
- Commit only when explicitly requested, in Chinese with the task name or ID.
|
- Commit only when explicitly requested, in Chinese with the task name or ID.
|
||||||
|
|
||||||
|
## Task Reuse
|
||||||
|
|
||||||
|
- A task is an execution contract, not a ticket for every tool call or fix.
|
||||||
|
Check current and directly related tasks first, not every historical task.
|
||||||
|
- Acceptance-related fixes stay in the current task. A different domain's fix
|
||||||
|
goes to its suitable existing task as a scoped follow-up; link the blocker
|
||||||
|
from the discovering task instead of duplicating implementation plans.
|
||||||
|
- Create only when independently managed work has no suitable existing owner.
|
||||||
|
Size, complexity, worktree isolation or a separate commit alone do not require
|
||||||
|
a new task. Tiny standalone edits may stay untracked unless tracking is requested.
|
||||||
|
- Task ownership, physical isolation and commit boundaries are separate choices.
|
||||||
|
Reuse does not authorize mixed diffs, scope creep, production changes or commits.
|
||||||
|
- Append only changed scope/acceptance/evidence, preserving historical results.
|
||||||
|
New risk or business decisions still need approval; unchanged approved fixes
|
||||||
|
do not. Do not bulk merge/archive tasks or reopen archived tasks to reduce counts.
|
||||||
|
|
||||||
|
## Active Task And Worktree Alignment
|
||||||
|
|
||||||
|
- On tracked-work entry, task scope change or execution worktree change, run
|
||||||
|
`python3 .trellis/scripts/task.py current --source` in the actual execution
|
||||||
|
root. Match the returned task to the intended work. Reuse unchanged context;
|
||||||
|
this is not a requirement to reload all specs or run checks every turn.
|
||||||
|
- For an already approved task, correct a mismatch using official
|
||||||
|
`task.py start <task>`, then read back current and phase with
|
||||||
|
`get_context.py --mode phase --platform codex`. Announce the task and phase
|
||||||
|
when switching. Starting a task does not replace plan or risk approval.
|
||||||
|
- Current task is session-scoped in `.trellis/.runtime/sessions/`, not the
|
||||||
|
legacy `.trellis/.current-task`. Do not write runtime JSON or shared pointers
|
||||||
|
manually. A missing legacy pointer is not evidence of runtime failure.
|
||||||
|
If identity is unavailable, report degraded mode and retain explicit task
|
||||||
|
context; do not claim the session pointer was repaired from exit code alone.
|
||||||
|
- Previously injected workflow-state can be stale after switching tasks. Use
|
||||||
|
official current/phase output for this turn; distinguish that verification
|
||||||
|
from actual next-turn platform injection. Do not enable hooks or change
|
||||||
|
user configuration merely to hide an execution mismatch.
|
||||||
|
- Run validation in the worktree whose files changed. Record its baseline,
|
||||||
|
task and evidence location. Isolated edits are not main-checkout integration;
|
||||||
|
do not copy unrelated changes or activate unrelated tasks to tidy a status.
|
||||||
|
- Inline mode changes who implements/checks, not the task contract. Keep
|
||||||
|
PRD/design/implementation, targeted check and spec/status update steps.
|
||||||
|
Static governance checks cannot prove that the correct task was used or
|
||||||
|
replace business acceptance and independent review.
|
||||||
|
- At stage handoff, record implementation, deployment, acceptance and pending
|
||||||
|
owner/action separately. Use official `task.py finish` only to clear a session
|
||||||
|
pointer when ending work; it does not complete or archive the task. Activate
|
||||||
|
the intended task explicitly if current reports `session-fallback`; official
|
||||||
|
resolution can infer the sole remaining session after a pointer is cleared.
|
||||||
|
Do not treat that inferred task as new execution approval. Activate
|
||||||
|
the next approved task explicitly when work actually resumes. Commit, push,
|
||||||
|
archive and production operations retain their separate approval boundaries.
|
||||||
|
|
||||||
## Risk-Scoped Execution
|
## Risk-Scoped Execution
|
||||||
|
|
||||||
- Pure consultation and small isolated edits do not need a task-creation
|
- Pure consultation and small isolated edits do not need a task-creation
|
||||||
|
|||||||
@@ -0,0 +1,65 @@
|
|||||||
|
# 人工操作前草稿
|
||||||
|
|
||||||
|
以下草稿待业务确认;尚未操作 0014、联系人员或处置三张单。源码核对结论及检查结果见 implement.md。
|
||||||
|
|
||||||
|
## 0014 一页观察清单
|
||||||
|
|
||||||
|
### 操作前确认
|
||||||
|
|
||||||
|
- 业务负责人:待指定;观察记录人:待指定;实际财务操作人及复核人:待指定。
|
||||||
|
- 先确认记录人、实际角色和现有入口;补资料前,在既有访问权限内记录候选禁用提示和缺项名称,不展开银行字段。再由另获授权且有对应权限的资料维护人补所属付款主体和真实银行信息;资料直接进系统,不进聊天或本记录。
|
||||||
|
- 非建行停止,不伪填;没有相应授权、缺付款前提或实际身份不符时停止该操作并记录真实阻塞。
|
||||||
|
- 由真实授权财务身份操作;如使用 finance smoke,另行明确授权启用,结束后立即停用并复核状态,未复核不得声称窗口关闭。
|
||||||
|
- 管理员代验不能算财务身份验收;此次不得自动执行账户启停、数据修改或付款。
|
||||||
|
|
||||||
|
### 现场记录表
|
||||||
|
|
||||||
|
| 观察节点(以实际流程为准) | 谁完成了什么/实际时间 | 下一位是谁 | 如何获知轮到自己 | 实际入口 | 是否人工催促/为何 | 结果或阻塞 |
|
||||||
|
| --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| 财务进入待组批、确认候选提示 | 待现场记录 | 待现场记录 | 系统通知/页面待办/口头/其他 | 待现场记录 | 待现场记录 | 待现场记录 |
|
||||||
|
| 财务创建并提交,交复核人 | 待现场记录 | 待现场记录 | 同上 | 待现场记录 | 待现场记录 | 待现场记录 |
|
||||||
|
| 复核完成,交财务登记付款 | 待现场记录 | 待现场记录 | 同上 | 待现场记录 | 待现场记录 | 待现场记录 |
|
||||||
|
|
||||||
|
三个观察节点不强行等同于三次角色交接;若真实流程另有交接,补记实际节点,不倒填时间。付款登记仍遵守既有复核及付款凭证要求,不把本清单当作支付批准。
|
||||||
|
|
||||||
|
### 自然样本与身份验收
|
||||||
|
|
||||||
|
| 样本 | 判定 | 记录边界 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| 真实财务进入并完成获准的组批/付款路径 | 未执行/通过/失败/未覆盖 | 记录实际角色、入口、动作和结果;管理员代验无效 |
|
||||||
|
| 财务看到被退回的 draft | 未自然发生则未覆盖 | 记录实际单据状态,不把 rejected 自动等同于 draft;不人为制造退回 |
|
||||||
|
| 审批人从待办进入报销 | 未自然发生则未覆盖 | 付款批次复核不替代报销审批样本;不为采样重走审批 |
|
||||||
|
|
||||||
|
完成后只交回脱敏角色、节点、入口、通知方式和催促记录;不附银行卡、真实凭证、合同正文或原始接口数据。
|
||||||
|
|
||||||
|
可选尾端观察:报销人是否收到付款完成提醒、从哪里获知、是否仍需人工告知;本人是否自行确认到账另记“已确认/未确认”。不查看银行资料,不把系统登记付款或通知送达当作银行实际入账,未自然发生就记未覆盖。
|
||||||
|
|
||||||
|
## 三张 rejected 单据收口规则草稿
|
||||||
|
|
||||||
|
现有路径只有单据参与人(owner/submitter)在既有权限内修改并重新提交;财务或管理员角色本身不获得代维护资格。业务需先将三单逐一对应到系统记录,并确认本人能否操作;本准备包不推断单据归属、人员离职状态或具体业务内容。
|
||||||
|
|
||||||
|
2026-09-06 只读汇总补充:当前库有 3 张 rejected 报销、归属于 1 个 owner,该 owner 的登录状态为 active、任职状态非 inactive。此结果不是“三位同事”,也不证明本人可联系、有空或愿意操作;未读取单号和人员标识,尚未逐单证明它们就是此前讨论的三张单。不能据此替业务选 A,也不能断言是离职导致卡住。
|
||||||
|
|
||||||
|
| 单据别名 | 本人是否可联系并可操作 | 路径选择(负责人定) | 截止时间(负责人定) | 到期核验与责任人 |
|
||||||
|
| --- | --- | --- | --- | --- |
|
||||||
|
| 单 A | 待确认 | A:本人修改重提/B:申请新运营动作 | 待确认 | 待确认 |
|
||||||
|
| 单 B | 待确认 | 同上 | 待确认 | 待确认 |
|
||||||
|
| 单 C | 待确认 | 同上 | 待确认 | 待确认 |
|
||||||
|
|
||||||
|
- A 路径:通知本人明确期限内修改重提,以系统实际重提记录留痕。到期未重提,现有系统不会自动关闭;负责人必须转为 B 的需求决策或明确承认仍未解决,不能宣称已作废或已代处理。
|
||||||
|
- B 路径:若本人不能操作或业务确需强制收口,另立带原因、权限、审计和状态语义的新运营动作 task,经 PRD 审批后实施;本准备包不选择作废还是纠错关闭、不执行数据库直改。
|
||||||
|
- 对 rejected 不使用删除、撤回或财务代维护作为到期动作。cancelled 枚举存在不代表已有可执行作废能力。
|
||||||
|
- 不把长期缺席/离职场景称为新回归,不恢复已关闭的 admin 豁免,不补造批准时间。
|
||||||
|
|
||||||
|
## 自动产物与人工关口
|
||||||
|
|
||||||
|
| 阶段 | 谁来做 | 本轮状态/触发条件 | 必须留下什么 |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| 自动准备 | 执行端 | 本 task 提供观察清单、收口草稿、三项只读结果和 G1–G10 可用性预检,交用户复核;不自动延伸实施 | implement.md 中的事实、证据和未验证边界 |
|
||||||
|
| 人工操作 | 业务负责人及授权操作人 | 先确认观察人员与清单,再另行授权资料维护及付款;三单逐一确认参与人、选择 A/B、截止时间并通知到人 | 真实交接记录、通知到人记录、真实重提记录或新需求决定 |
|
||||||
|
| 自动整理 | 执行端 | 收到脱敏现场记录后整理交接矩阵、自然样本覆盖和真实财务路径结果;盘点和 IM 差异已可作为独立方案输入,不必等付款 | 事实与推断分开;未发生的自然样本保持未覆盖 |
|
||||||
|
| 人工批准 | 用户/业务负责人 | 审核产物与后续 PRD;存量回填、运营关闭、生产配置、账号启停及付款各自另批 | 明确范围、责任人和授权,不把复核通过等同于生产写入批准 |
|
||||||
|
|
||||||
|
唯一主体 PRD 不再等待 0014;合同测试修复及 G1–G10 完整复核也不等业务交接。只有统一待办的具体设计继续等真实交接记录。本轮不自动启动这些后续项;没有任何队列在后台推进。
|
||||||
|
|
||||||
|
2026-09-06 用户已复核原准备包通过,可以交业务;业务宜先匹配当前 3 张 rejected 是否就是旧三单,再决定是否一次联系同一参与人。合同事项已上调为门禁完整性问题,先追溯候选验收与发布的关联,再另行批准修复,不先改单条测试。此技术追溯不重新阻塞已通过的业务清单。
|
||||||
@@ -0,0 +1,224 @@
|
|||||||
|
# 执行与只读证据
|
||||||
|
|
||||||
|
## 已批准范围和基线
|
||||||
|
|
||||||
|
- 基线 HEAD:66f25b1;origin/main:492920c;两笔 Trellis 本地提交不在本轮推送范围。
|
||||||
|
- 用户批准第一批准备产物;当前 task 与上一 Trellis 升级 task 分开,不归档或改写上一任务。
|
||||||
|
- 产品代码、生产数据和全局配置只读;仅本 task 文档及忽略的隔离证据写入。允许在临时目录使用合成 fixture,不执行真实写接口。
|
||||||
|
|
||||||
|
## 执行状态
|
||||||
|
|
||||||
|
- [x] 核实 rejected 现有动作与历史取舍,完成观察清单/收口草稿。
|
||||||
|
- [x] 先确认 G1–G10 改前备份、批准方案、当前内容入口可用。
|
||||||
|
- [x] 主体存量只读汇总盘点。
|
||||||
|
- [x] 合同只读超时具体用例、失败步骤与环境归因。
|
||||||
|
- [x] IM 注册表/环境配置/运行时有效值核对。
|
||||||
|
- [x] 汇总待人工决定项,完成治理/敏感检查,准备交用户审阅;独立复核尚待用户进行。
|
||||||
|
|
||||||
|
## 证据口径
|
||||||
|
|
||||||
|
每项分别记录源码事实、环境实测、结论和未验证范围;不将读取配置等同于通知送达,不把 403 原因诊断等同于财务业务验收,不把普通本地测试绿等同于历史超时已归因。
|
||||||
|
|
||||||
|
## 1. 业务草稿与 rejected 动作事实
|
||||||
|
|
||||||
|
可交给观察人填写的清单和三单 A/B 草稿在 design.md。先确认观察分工与清单,再另行授权付款;现场结果只按实际发生填写,补资料前先记录实际可见的缺项提示。记录角色、入口、获知方式和是否人工催促,不补造时间、不为了取样制造退回。
|
||||||
|
|
||||||
|
源码核对:
|
||||||
|
|
||||||
|
- `server/src/routes/reimbursements.js:648` 的参与人判定仅为 owner/submitter;10 个维护调用点经过该判定,admin/finance 角色本身没有豁免。
|
||||||
|
- `server/src/routes/reimbursements.js:2816` 删除仅限 draft;`:4386` 撤回仅限 reviewing,撤回回到 draft,不是作废。
|
||||||
|
- 报销 cancelled 枚举不提供可执行的作废入口;不能把工作流任务的取消误认成报销本体作废。
|
||||||
|
- 已接受的取舍见 `.trellis/tasks/08-28-reimbursement-nonparticipant-readonly-projection/design.md:73`;本轮不是重开该权限缺陷。
|
||||||
|
|
||||||
|
业务出口仍由负责人选择:A 本人在既有权限内限期修改重提;B 新运营动作另立 task,明确原因、权限、状态和审计后审批。A 到期未履行不会自动关闭,必须作 B 的需求决定或如实记录未解决,不能写“财务代处理”。
|
||||||
|
|
||||||
|
本次汇总显示 3 张 rejected 归 1 个 owner,其登录为 active、任职非 inactive。未读单号、人员标识或正文,不将汇总强行匹配到旧三单;更不将 active 等同于可联系或能执行。业务仍需逐单确认。
|
||||||
|
|
||||||
|
## 2. 生产只读通道与身份核验
|
||||||
|
|
||||||
|
正式汇总快照:2026-09-06 12:51:02(Asia/Shanghai),运行中的应用 build 为 `f223bfb72fb2`。
|
||||||
|
|
||||||
|
- 按现有部署 spec 的身份消歧合同,选择唯一符合非 root、冻结部署目录及环境文件数字 UID 归属、Docker 访问条件的既有 SSH 身份;不新增通道、不修改 SSH 配置。
|
||||||
|
- 对照冻结备份 unit 的 Compose project 定位运行中 server/db。容器内解析应用连接目标,仅返回布尔值及数据库名摘要:应用 DB host 解析到所选 db 容器;端口与 schema 符合检查前提;应用数据库名与查询数据库名摘要一致。没有把默认 POSTGRES_DB 未经核验当作应用生产库。
|
||||||
|
- 随后在同一只读探针内重新核验身份并重做汇总。连接设置 `default_transaction_read_only=on`,事务为 `REPEATABLE READ READ ONLY`,实际确认 `transaction_read_only=on`;statement timeout 10 秒、lock timeout 1 秒,最后 ROLLBACK。
|
||||||
|
- SQL 只取计数、状态分组和通知 routing 指定字段,不取员工标识、卡号、开户行、合同正文、通知内容或密钥。账号状态只读,不登录生产业务身份或修改账号。
|
||||||
|
|
||||||
|
脱敏复核入口(均在忽略的证据目录内):
|
||||||
|
|
||||||
|
- `artifacts/qa-flow/payment-observation-readonly-preparation/readonly-inventory.sql`
|
||||||
|
- `artifacts/qa-flow/payment-observation-readonly-preparation/production-readonly-results.json`
|
||||||
|
- `artifacts/qa-flow/payment-observation-readonly-preparation/application-database-identity.json`
|
||||||
|
|
||||||
|
最初的默认库汇总未立即发布结论;正式结果以上述应用身份匹配后的重查为准。读取配置及 SELECT 不等于任何写入授权。
|
||||||
|
|
||||||
|
## 3. 唯一付款主体盘点
|
||||||
|
|
||||||
|
| 口径 | 本次只读结果 |
|
||||||
|
| --- | --- |
|
||||||
|
| 主体总数/启用且未归档 | 1/1 |
|
||||||
|
| 员工记录总数 | 8 |
|
||||||
|
| 未归档且登录 active 的员工记录 | 7 |
|
||||||
|
| 上述记录缺 legal_entity_id | 7/7 |
|
||||||
|
| 上述记录绑定失效主体 | 0;不能把未绑定算成绑定有效 |
|
||||||
|
| 在职生命周期记录(probation/active/offboarding,未归档) | 7,全部缺主体 |
|
||||||
|
| 已归档员工记录 | 1,也缺主体,不与在用范围混算 |
|
||||||
|
| approved 报销/owner 数 | 1/1;该 owner 缺主体,登录未停用 |
|
||||||
|
|
||||||
|
**判断:不是只针对单个员工的防御性补丁。** 当前全部 7 个未归档 active 员工记录都存在主体缺项,主体生命周期 PRD 可立即使用本盘点作为输入,不必等 0014 完成。
|
||||||
|
|
||||||
|
口径限制:这里是员工记录数,未按真人与 smoke 身份拆分;不是“7 位真人都已触发付款失败”。approved 汇总未排除组批占用,也未执行完整 readiness,因此不冒充付款候选总数;没有读取单号,不能直接把该唯一 approved 记录认定为 0014。未检查真实银行资料、付款账户可用性或指定应该绑定哪个主体。
|
||||||
|
|
||||||
|
三段合同不变:新增时按经批准的唯一主体规则显式落库;存量先盘点、再获单独回填批准;付款阶段仍严格报错,不静默推导。当前 1 个启用主体只是快照,不授权立即回填,也不替代未来写入时重新检查唯一性。
|
||||||
|
|
||||||
|
## 4. 合同只读超时归因
|
||||||
|
|
||||||
|
### 精确复现
|
||||||
|
|
||||||
|
- 环境:本地 Vite、单 worker、无重试、API mock 与合成角色/合同;不访问生产合同。
|
||||||
|
- 用例:`client/tests/e2e/payment-reviewer-permissions.spec.ts:380`,合同只读人员看不到新增编辑续约和归档动作。
|
||||||
|
- 实际结果:**1 failed,180000ms test timeout**。没有调整超时或断言,没有重试至绿。
|
||||||
|
|
||||||
|
执行命令(工作目录 client;本轮启动的 Vite 已停止):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
E2E_MODE=local E2E_BASE_URL=http://127.0.0.1:5189 CI=1 \
|
||||||
|
node node_modules/@playwright/test/cli.js test \
|
||||||
|
tests/e2e/payment-reviewer-permissions.spec.ts \
|
||||||
|
--grep '合同只读人员看不到新增编辑续约和归档动作' \
|
||||||
|
--workers=1 --retries=0 --reporter=line --trace=on \
|
||||||
|
--output=../artifacts/qa-flow/payment-observation-readonly-preparation/contract-baseline
|
||||||
|
```
|
||||||
|
|
||||||
|
### 因果链与分类
|
||||||
|
|
||||||
|
1. 合成身份登录、进入合同页、合同行可见,以及“新增合同/编辑不可见”前置断言已经过。
|
||||||
|
2. `payment-reviewer-permissions.spec.ts:397` 等待该行名为“更多”的 button,直至超时;DOM/trace 中该行只有“查看详情”链接,没有“更多”按钮。
|
||||||
|
3. 当前 `client/src/pages/ContractsRegistryPage.tsx:313` 的行操作已是详情入口。测试在 `5d0a5f9`(2026-07-18)引入,列表在 `2185177`(2026-08-08)改为详情工作区;对应设计见 `.trellis/tasks/archive/2026-08/08-05-contract-detail-workspace/design.md:80`。
|
||||||
|
|
||||||
|
分类为**测试契约漂移:用例仍操作已移除的列表菜单**,不是靠增大等待时长可解决的慢启动。这解释了本次对既有超时用例的复现,不把未保存的历史运行环境也声称逐次复现。
|
||||||
|
|
||||||
|
后续应按真实详情入口重建只读权限回归,继续具体断言新增、编辑、续约和归档不可用;不能只删 click 或只断言详情可见。本轮仅归因,**测试仍失败、修复未实施,不能计入通过结果**;超时后的续约/归档断言尚未执行。
|
||||||
|
|
||||||
|
证据在 `artifacts/qa-flow/payment-observation-readonly-preparation/contract-baseline/`:失败状态、DOM 摘要、截图、视频和 trace,均为合成数据。没有真实合同截图或正文。
|
||||||
|
|
||||||
|
## 5. IM routing 三层核对
|
||||||
|
|
||||||
|
### 代码层、环境层与有效路由层
|
||||||
|
|
||||||
|
| 层级 | 实测/源码证据 | 不代表什么 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| 代码注册 | 生产的 NOTIFICATION_TYPES 与 IM_SUPPORTED_NOTIFICATION_TYPES 均包含三种 returned;注册表及 imRouting 源码摘要与本地 HEAD 一致 | 不代表配置放行或已送达 |
|
||||||
|
| 环境配置 | 冻结环境文件 IM_NOTIFIER_ENABLED=true;未用示例文件冒充现状 | 不单独证明运行中容器值 |
|
||||||
|
| 运行中配置 | server 中实际 getConfig().imNotifierEnabled=true | 不代表某个收件人有有效企微绑定 |
|
||||||
|
| 应用 DB routing | 1 条启用 wecom;allowedTypes 为 7 项,domainScopes 仅 workflow/reimbursement,roleCodes 为空 | 没有读取 channel 密钥/模板或发送内容 |
|
||||||
|
| 有效路由计算 | 将只读提取的 routing 交给生产容器现有纯函数 matchesNotificationChannel,使用注册表解析的实际域 | 这是当前配置匹配结果,不是通知入队或送达验收 |
|
||||||
|
|
||||||
|
本次 allowedTypes:workflow.task_assigned、reimbursement.approved、reimbursement.rejected、reimbursement.returned、reimbursement.paid、payment_batch.review_requested、payment_batch.execution_requested。
|
||||||
|
|
||||||
|
| 类型 | 代码注册/IM 支持 | allowedTypes | domainScopes | 当前匹配启用 channel 数 |
|
||||||
|
| --- | --- | --- | --- | --- |
|
||||||
|
| reimbursement.returned | 是/是 | 包含 | reimbursement 包含 | 1 |
|
||||||
|
| purchase_request.returned | 是/是 | 不包含 | procurement 不包含 | 0 |
|
||||||
|
| travel_request.returned | 是/是 | 不包含 | travel 不包含 | 0 |
|
||||||
|
| reimbursement.rejected(区分旧三单状态所需) | 是/是 | 包含 | reimbursement 包含 | 1 |
|
||||||
|
|
||||||
|
**旧“三种 returned 都未放行”的前提已被现状推翻。** 当前需讨论的路由缺口是采购、出差两类,而且要同时处理类型和业务域,不能只往 allowedTypes 加名称。若后续批准变更,应保留其余既有路由,并用双层差异交复核;本轮未生成或应用生产写入命令。
|
||||||
|
|
||||||
|
空 roleCodes 表示不额外按角色过滤,不是全部拒绝。imEnqueue 每次从应用 DB 查询启用渠道后调用匹配函数,不把环境文件中的总开关当作 allowlist。
|
||||||
|
|
||||||
|
### Worker 与送达边界
|
||||||
|
|
||||||
|
当前没有独立 running worker 容器,但 server 的 jobsEnabled=true、jobDriver=pgboss。`server/src/app.js:407` 调 startJobs,`server/src/jobs/jobSystem.js:14` 支持内嵌 pg-boss,`server/src/jobs/pgBossJobs.js:310` 与 `:400` 注册和调度 integration outbox。因此“没有独立 worker 容器”不能单独判为通知服务缺失。本轮只核对配置和启动代码,不声称队列健康或每次任务已执行。
|
||||||
|
|
||||||
|
没有读取真实通知 payload、收件人企微信息、历史 outbox 送达记录,也没有发送探针消息。报销 returned/rejected 当前匹配不能证明旧三单当时曾入队或送达;采购/出差当前不匹配也不能解释三张报销未回复。历史配置、事件是否产生、送达和本人是否看到,均保持未验证。
|
||||||
|
|
||||||
|
## 6. G1–G10 可用性预检
|
||||||
|
|
||||||
|
**可开展后续完整只读复核,不因备份缺失阻塞;本轮没有替代该复核。**
|
||||||
|
|
||||||
|
| 私有备份 ID | 归档 | 可读性与条目数 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| hyb-oa-rules-stage2-FcbImknm | global-before.tar.gz | 可读,118 条;14 个 SKILL.md 和配置入口 |
|
||||||
|
| 同上 | project-before.tar.gz | 可读,92 条 |
|
||||||
|
| 同上 | duplicate-policy-before.tar.gz | 可读,2 条 |
|
||||||
|
| hyb-oa-global-five-VmWeZjgM | skills-before.tar.gz | 可读,29 条;5 个 SKILL.md |
|
||||||
|
|
||||||
|
- 批准方案 `.trellis/tasks/09-05-trellis-upgrade-rule-cleanup/design.md` 的 G1–G10 条目全部存在,各项改前文件与当前可读入口均能对应。
|
||||||
|
- 10 个全局 Trellis 后备入口存在;find-skills 的两个当前入口仍解析到同一目标;G6–G10 五个当前技能文件可读。
|
||||||
|
- 原 discovery/validation JSON 可解析;本轮计算归档摘要并记录可用性,不将旧日志当作独立内容复核通过。
|
||||||
|
- 未展开或输出用户级配置秘密,未解包覆盖任何当前文件,未修改技能、配置、hooks 或其发现策略;没有验证真实客户端加载状态。
|
||||||
|
|
||||||
|
脱敏回执:`artifacts/qa-flow/payment-observation-readonly-preparation/global-skills-availability.json`。备份位置保留在既有私有状态目录,正文只记备份 ID,不复制完整路径或配置内容。
|
||||||
|
|
||||||
|
## 7. 下一步人工关口与未启动项
|
||||||
|
|
||||||
|
1. 用户逐项审阅本准备包;业务指定 0014 观察人与真实财务身份,确认清单后再另行授权补资料/付款。非建行停止,不伪填。
|
||||||
|
2. 业务逐单定位旧三单、确认参与人能否操作、决定 A/B 和明确期限,通知到人;没有“财务代处理”的伪出口。
|
||||||
|
3. 合同测试修复、唯一主体 PRD、IM 两类差异方案及 G1–G10 全量复核均已有前置输入,不必等付款;本轮不自动开下一 task 或进入实施。
|
||||||
|
4. 执行端收到脱敏现场记录后才能整理真实交接与自然样本;仅统一待办的具体设计等待这些证据。未发生的样本不算覆盖,管理员代验不算财务验收。
|
||||||
|
5. 所有 push、归档、生产配置、账号启停、回填及付款继续分别等待明确授权。当前没有后台自动推进中的工作。
|
||||||
|
|
||||||
|
## 8. 本轮检查与交付状态
|
||||||
|
|
||||||
|
- 合同精确用例:失败已归因,保持 1 failed,不计入 PASS。
|
||||||
|
- `python3 .trellis/scripts/task.py validate .trellis/tasks/09-06-payment-observation-readonly-preparation`:PASS;inline 下两个 manifest 各 0 条,未为未来可能的 sub-agent 模式伪造上下文。
|
||||||
|
- `node scripts/qa/check-trellis-governance.mjs`:PASS,0 errors/0 warnings,1270 个 Trellis 文件纳入敏感检查。
|
||||||
|
- `node scripts/qa/check-sensitive-content.mjs`:PASS,0 findings;`git diff --check`:PASS。新增 task 文件另做 no-index 空白检查,避免仅检查 tracked diff 漏掉新文件。
|
||||||
|
- 本 task 仅准备证据与草稿,没有修改产品运行时代码、spec、权限、状态机、部署工具、hooks 或全局技能。没有修复测试、触碰真实银行资料、提交、push、归档或部署。
|
||||||
|
- 旧 Trellis task 的提交追溯及全局技能完整审查未被本轮标成完成。本 task 由 start 记录的 branch=base_branch=main 保持原状,不借只读准备擅自创建分支或归档。
|
||||||
|
- 原准备包已获用户独立复核通过,可交业务;追加的门禁只读追溯等待增量复核,状态保持 review。不表示业务操作、测试修复或后续 PRD 已获批准;HEAD 保持 66f25b1,origin/main 本地跟踪引用保持 492920c。
|
||||||
|
|
||||||
|
## 9. 用户复核后的门禁完整性只读追溯(2026-09-06)
|
||||||
|
|
||||||
|
### 修正定性与调查边界
|
||||||
|
|
||||||
|
用户指出该超时位于 acceptanceSpecs,并会令本地候选门禁失败。原报告只定位到测试契约漂移,漏掉了它的门禁影响,应由执行端纠正:**这是候选验收与发布阻断未关联的完整性问题,不再按普通测试债排队。** 本轮先查调用链和历史留痕,没有修改测试、放宽断言、跑完整候选门禁或访问生产。
|
||||||
|
|
||||||
|
### 机器调用链已经证实
|
||||||
|
|
||||||
|
- `scripts/qa/route-manifest.json:23` 登记旧合同只读用例所在 spec;`scripts/qa/run-local-candidate.sh:84` 将全部 acceptanceSpecs 与 witness 合并,full/focused 均不按本次产品改动缩减。
|
||||||
|
- runner 检查 Playwright 与结果验证器的退出状态;失败时 exit 1,只有 full 的成功分支能声明 LOCAL_CANDIDATE_PASS。没有发现该 runner 吞掉失败退出码的证据。
|
||||||
|
- `.trellis/spec/hyb-oa/deployment-trialrun.md:800` 定义本地候选合格的范围;`.trellis/spec/hyb-oa/frontend-react-vite-design.md:2686` 与 `:2708` 要求受管验收实际执行且零 failed/skipped。声明某个局部测试通过不能替代它。
|
||||||
|
- 实际发布链为 `production-identity-bootstrap.mjs → deploy-existing.sh → deploy.sh`。`deploy-existing.sh:70` 检查来源,随后检查生产目标、迁移等前置;这条链没有调用本地候选 runner,也没有消费绑定当前候选提交的本地验收回执。
|
||||||
|
- `deploy/trialrun/check-source-provenance.mjs:48` 检查工作树、提交、分支与上游发布状态;source provenance 通过并不包含“浏览器候选验收通过”。
|
||||||
|
- `scripts/qa/run-release-gate.sh` 同样不调用本地候选 runner。其 full-local 间接执行另一套 `npm run test:e2e:full`(全部 Playwright),不能与 run-local-candidate 的 full 混为一谈;static 模式也不是浏览器验收。
|
||||||
|
|
||||||
|
因此必须区分:**规约中的受管候选验收失败,会阻断本地候选 PASS;但现有发布入口不以该结果为必要输入,所以不能自动阻断部署。** 这不是数据库或页面自己恢复了,也不是清洁工作树证明所有门禁都过了。
|
||||||
|
|
||||||
|
### 历史证据:不只读旧结论,核对工具调用与返回
|
||||||
|
|
||||||
|
检查范围为本机可索引的 18 份本项目历史会话,核对 2026-08-08 至 2026-09-05 的工具事件;时间表使用 Asia/Shanghai。区分实际执行、读源码、写文档和会话引用,不把源码中打印出来的 PASS 字符串当作执行回执。
|
||||||
|
|
||||||
|
| 时间/来源 | 已证实事实 | 证明上限 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| 2026-07-18、2026-08-01 的既有 task 记录 | 分别记录 full 44/44、focused 50/50 通过 | 早于合同列表迁移;本轮未重跑,不可复用成后续候选的通过证据 |
|
||||||
|
| 2026-08-08 01:21 工具调用 | 批量本地检查中实际请求了 run-local-candidate.sh list | 只解析;本轮未取得该调用完整结束回执,不将它记成 full/focused 通过 |
|
||||||
|
| 2026-09-04 23:03 工具返回 | 旧合同只读用例等待“更多”超时,明确 180000ms;该次返回 1 failed、4 passed | 确认旧用例在 09-05 前已经报红;不是 full runner 的返回 |
|
||||||
|
| 2026-09-05 13:14–13:19 工具调用/返回 | 未加 grep 的 payment-reviewer-permissions spec 被执行,返回中再次出现该合同用例红行 | 已见失败进度;本轮没有将该进程完整最终退出码标成已验证 |
|
||||||
|
| 2026-09-05 13:31–13:42 工具调用/返回 | 后续直接 Playwright 使用明确的 --grep 选择付款/B2/采购等用例,返回 17 passed、exit 0;筛选不包含合同只读用例 | 这是定向回归,不是 run-local-candidate.sh focused,也不是合同已修复 |
|
||||||
|
| 2026-09-05 19:01–19:04、21:07–21:09 工具调用/返回 | 两次非只读 bootstrap 发布进程均返回 exit 0;对应 task 分别记录 a837912、f223bfb 的生产发布 | 证明发布入口在上述已知失败存在后仍可完成;不等于它曾接收并忽略一个 full runner 的 exit 1 |
|
||||||
|
|
||||||
|
直接回执定位保存在 `artifacts/qa-flow/payment-observation-readonly-preparation/candidate-gate-history-audit.json`,仅含会话标识、调用标识、时间、测试计数和已验证信号,不附会话原文、完整账号、生产连接信息或原始业务响应。
|
||||||
|
|
||||||
|
原任务笔记与工具留痕相符:`.trellis/tasks/09-05-error-explainability-payment-readiness/implement.md:112` 已写扩大测试出现合同超时、随后改为定向集合;第 10 节明确失败未归因、不计通过,然后记录用户允许发布。因此“跑了失败却完全没留记录”至少不适用于这一次;**留下了失败记录,但没有识别并报告它令受管候选验收不合格的后果。**
|
||||||
|
|
||||||
|
### 回答“为什么没有阻断”与仍不能断言的事
|
||||||
|
|
||||||
|
能够证实的链条是:
|
||||||
|
|
||||||
|
1. 新合同详情已实现并做局部回归,但旧受管合同验收仍指向已移除的菜单。
|
||||||
|
2. 最近两轮真实工具留痕表明旧用例确实报红;09-05 的后续定向集合排除了它,并将未归因失败留作合同域后续事项。
|
||||||
|
3. 发布使用来源/生产前置检查和获批的独立部署入口,不要求提供该候选的完整本地验收结果;因此“定向绿+来源前置通过+发布获批”仍能走到部署完成。
|
||||||
|
|
||||||
|
这是**执行选择与机器依赖两层断开**:执行端把受管验收失败当作任务外事项,而部署链没有把完整候选结果设为前置。普通发布批准与已披露的一条测试失败,不能被倒写为用户明确豁免完整候选门禁;本轮没有找到该种专门豁免记录。
|
||||||
|
|
||||||
|
本机上述范围内未找到漂移后 full/focused 候选执行的可核回执。但这**不证明整个月从未运行**:不覆盖其他 worktree、未索引客户端、外部 CI/机器和已清理记录。不能以未找到记录代替每次部署的完整调查,更不能把最近两次的处理方式套用到全部历史候选。
|
||||||
|
|
||||||
|
另有留痕缺口:run-local-candidate.sh 使用临时 JSON 与 stderr 文件,cleanup 在成功或失败后均删除它们;脚本本身没有持久化带候选提交、模式和结果的验收回执。它解释了为何仅扫描 artifacts 不足以证明“从未跑过”,但不能证明某条丢失的回执曾经通过。
|
||||||
|
|
||||||
|
### 优先级与交接
|
||||||
|
|
||||||
|
- 先按门禁完整性问题另行确定修复范围:实际部署入口如何关联当前候选的必需验收、如何留存结果、合法例外如何明确批准并留痕;不能只把单条测试改绿就宣布完整性收口。本轮不立新开发 task、不改治理或发布脚本。
|
||||||
|
- 合同用例后续仍须按详情入口具体验证只读身份的新增、编辑、续约、归档边界;当前旧用例超时后的断言保持未验证。先查清完整性再批准修复,不先删 click、增加 timeout 或缩减 acceptanceSpecs。
|
||||||
|
- 原业务准备包已经用户复核通过,不因本追溯重新挂起;业务优先匹配 3 张 rejected 是否就是旧三单。观察清单补充付款提醒/本人自行确认到账的可选尾端记录,严格区分通知、登记付款与银行入账。
|
||||||
|
- 本节为主会话新增只读证据,尚待用户增量复核;没有把原准备包的 PASS 延伸为本节独立复核通过。
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
# 付款观察与运营现状只读准备
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
把已确认的后续安排变成人可执行、可逐项复核的准备包,防止 0014 付款完成却丢失交接证据,并用只读事实决定后续需求。用户已确认执行范围,不重做方案审批。
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
- 一页 0014 观察清单草稿,覆盖真实财务身份与实际交接;自然样本未发生只记未覆盖。
|
||||||
|
- 三张 rejected 单据的收口规则草稿,只允许本人修改重提或另行批准新运营动作,不虚构财务代维护。
|
||||||
|
- 三项只读检查:唯一付款主体存量盘点、合同只读用例超时归因、IM routing 三层现状核对。
|
||||||
|
- G1–G10 改前备份与批准方案的可用性预检,不开展或声称全量独立复核。
|
||||||
|
- 产物集中在本 task 的 design.md(业务草稿)和 implement.md(检查结果与交接);隔离技术证据放忽略的 artifacts 目录。
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
1. 0014 动作前确认记录人、实际操作身份、观察入口及人工催促字段;不制造退回或重走审批来凑样本。
|
||||||
|
2. 区分 403 诊断已收口与真实财务身份业务路径验收未完成;管理员代验不得抵扣。
|
||||||
|
3. rejected 无行政代维护路径是已接受的权限取舍,不作为新回归;业务自行选择限期本人重提,或另立新运营动作 task。
|
||||||
|
4. 主体盘点仅返回数量和缺项汇总,不读取银行信息。新增自动绑定/存量另批回填/付款严格报错不推导的三段合同保持。
|
||||||
|
5. IM 注册表、环境配置与运行时有效值分别标明证据层级,代码默认值不能冒充生产有效值;通知缺口与三单未回复的因果保持未证实。
|
||||||
|
6. 超时归因只用本地合成测试及可脱敏日志,不接触真实合同正文;不通过放宽断言、重试至绿或改产品代码收口。
|
||||||
|
|
||||||
|
## Out Of Scope
|
||||||
|
|
||||||
|
不改产品、权限、状态机、hooks、全局技能或生产配置;不读真实银行卡、合同正文、凭据或原始业务 payload;不回填、不启停账号、不发企微、不付款、不作废单据、不补造批准时间。不提交、push、归档、部署或清理既有工作区。
|
||||||
|
|
||||||
|
## Acceptance
|
||||||
|
|
||||||
|
- [x] 观察清单能交给实际人员使用,人工确认项、自然样本未覆盖与硬停止条件明确。
|
||||||
|
- [x] 收口规则逐项符合源码,选择权与新开发边界明确。
|
||||||
|
- [x] 主体盘点给出汇总及受影响范围,或精确说明缺少的只读前提。
|
||||||
|
- [x] 合同超时锁定具体用例/失败步骤/环境与归类;不能定位则保留明确未归因及证据缺口。
|
||||||
|
- [x] IM 三层现状分开核对,未知项不报通过,不发送通知。
|
||||||
|
- [x] G1–G10 备份存在性、可读性、批准方案与当前内容入口已核对,未冒充内容审查通过。
|
||||||
|
- [x] 任务治理、敏感扫描和差异检查通过;只有本 task 文档成为未跟踪改动,交用户逐项审阅。
|
||||||
|
|
||||||
|
原准备包已于 2026-09-06 获用户独立复核通过,可以交业务;不代表合同测试修复完成或真实财务业务验收通过。用户随后要求先查清候选门禁为何未阻断部署,新增只读追溯见 implement.md 第 9 节,等待增量复核;本 task 保持 review,不提交、归档或进入产品修复。
|
||||||
|
|
||||||
|
## Test Plan
|
||||||
|
|
||||||
|
检查源码与已批准历史设计;通过现有获准只读通道执行最小汇总查询;本地隔离执行精确合同浏览器用例;核对备份归档清单且不展开敏感配置。最后运行 task validate、Trellis governance、敏感扫描及 git diff --check。任何访问前提缺失只阻塞该检查,不延伸为写入授权。
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"id": "payment-observation-readonly-preparation",
|
||||||
|
"name": "payment-observation-readonly-preparation",
|
||||||
|
"title": "付款观察与运营现状只读准备",
|
||||||
|
"description": "按已确认顺序准备0014观察清单、基于现有权限的三单收口草稿、主体盘点/合同超时/IM现状三项只读结果,并确认G1–G10备份可用性;不改产品代码或生产数据。",
|
||||||
|
"status": "review",
|
||||||
|
"dev_type": null,
|
||||||
|
"scope": "readonly-preparation",
|
||||||
|
"package": null,
|
||||||
|
"priority": "P2",
|
||||||
|
"creator": "shunli",
|
||||||
|
"assignee": "shunli",
|
||||||
|
"createdAt": "2026-09-06",
|
||||||
|
"completedAt": null,
|
||||||
|
"branch": "main",
|
||||||
|
"base_branch": "main",
|
||||||
|
"worktree_path": null,
|
||||||
|
"commit": null,
|
||||||
|
"pr_url": null,
|
||||||
|
"subtasks": [],
|
||||||
|
"children": [],
|
||||||
|
"parent": null,
|
||||||
|
"relatedFiles": [],
|
||||||
|
"notes": "2026-09-06 用户确认自动准备→人工操作→自动整理→人工批准的顺序,要求产出观察清单、按 rejected 实际动作编写的收口草稿及三项只读结果;另确认 G1–G10 备份可用性。仅当前 task 文档与隔离证据写入获准,不实施新运营动作、不修改产品代码、不操作生产数据或外部通知,不提交/push/归档/部署。",
|
||||||
|
"meta": {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,202 @@
|
|||||||
|
# E2E 认证前置统一 — 阶段化设计
|
||||||
|
|
||||||
|
2026-09-07 最新状态:阶段 0 与在线对照均已获用户复核认可;原 31+2 迁移继续暂缓。环境实现合同唯一入口为 .trellis/tasks/09-06-release-gate-integrity/design.md §10(待审),本任务保留取证,不平行维护另一套 runner 方案。207 浏览器清单已撤销决策资格,原始观测及脚本保留;这不是逐条认定 207 全为假失败,也不代表其他真实红项已查清。
|
||||||
|
|
||||||
|
## 1. 已有 trace:cookie 不是已证明的先因
|
||||||
|
|
||||||
|
本轮读取 trace-comparison-20260907-01 的 single 合同只读用例,未重跑浏览器。原件位于 artifacts/qa-flow/release-gate-integrity/trace-comparison-20260907-01/single/report/test-results/ 下的该用例目录;SHA-256 为 4b0f4c51736817f1e7035f553fbd9546a171a650ea88ab3dd9ce61a826027121。
|
||||||
|
|
||||||
|
检查 archive 的 21 条 network 记录及 browser trace 的 Route.fulfill 事件。相对首次 goto 起点:
|
||||||
|
|
||||||
|
| 事件 | 起始偏移 | 直接观测 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| GET /login | +61.3ms | 200;request Cookie header 不存在,cookies 数组没有 has_session=1;该响应未记录设置此标记 |
|
||||||
|
| POST /api/auth/refresh | +1129.3ms | 200;request Cookie header 不存在,cookies 数组没有 has_session=1 |
|
||||||
|
| Route.fulfill,call@28 | +1145.3ms | 参数 status=200 且 headers 指定 Set-Cookie: has_session=1;调用完成且没有错误 |
|
||||||
|
| GET /api/me | +1376.3ms | 200;request Cookie header 和 cookies 数组均有会话标记 |
|
||||||
|
|
||||||
|
- 全 trace 没有 /api/auth/login 请求,且只有上述一个包含会话标记的 fulfill 调用;payment-reviewer-permissions.spec.ts:194 的合并处理器在 :198 指定该标记。结合时序、调用和源码,首次可见设置动作对应 refresh 合成响应,不是 /login 前已经观察到的 cookie。
|
||||||
|
- network 序列本身没有保留此 Set-Cookie header。必须写成“Route.fulfill 参数里观察到”,不能伪装成从 network response header 直接读到;请求开始时间也不等于响应完成时间。
|
||||||
|
- 请求及处理器参数不是任意 JS cookie 写入的完整审计。本证据反驳“refresh 必然证明事先已有 cookie”的推导,不声称排除全部未记录写入。
|
||||||
|
- AuthContext.tsx:365 在离线且有可用快照时走离线快照;:370 在无会话提示且在线时直接未认证。离线且无可用快照时,即使没有会话标记,也可能继续 refresh。
|
||||||
|
- 旧 trace 未捕获 navigator.onLine、离线快照可用性或 JS 调用栈,不把“可能离线”定为根因,也不将未来观测追认成旧现场值。
|
||||||
|
|
||||||
|
## 2. 认证夹具状态模型
|
||||||
|
|
||||||
|
| 起点/事件 | refresh | 场景行为 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| guest,未显式登录 | 未认证 | 可驱动表单,不预先返回身份 |
|
||||||
|
| guest → 登录成功 | authenticated | 登录及 /me 成功,后续刷新可恢复 |
|
||||||
|
| authenticated 显式起点 | 成功恢复 | 直接进入业务入口,不再填表单 |
|
||||||
|
| authenticated → 注销 | guest | 后续 refresh 未认证,旧身份不复活 |
|
||||||
|
|
||||||
|
参照 local-candidate-witnesses.spec.ts:199 的初始 false、:241 的登录、:252 的 refresh 判断和 :260 的注销。其状态合同正确不等于该文件的原失败通过,也不构成默认重写授权。
|
||||||
|
|
||||||
|
login-portal-ux 混合访客、Portal 登录及 bootstrap 恢复场景;mobile-approvals-offline 前两条使用本地真实 API,第三条才安装合成 mock。迁移以场景调用图为单位,不全文替换。
|
||||||
|
|
||||||
|
可采用共享有状态 helper,具体接口和写入范围在阶段 0 后交审。不得修改 AuthContext、覆盖 navigator.onLine、删除 full navigation 或不再检查 /me 以规避矛盾;PWA/offline 场景保留专用网络语义,不无差别关闭 Service Worker。
|
||||||
|
|
||||||
|
## 3. 阶段 0:本地取证与静态盘点(2026-09-07 已独立复核批准)
|
||||||
|
|
||||||
|
1. 冻结候选、获准 21 文件摘要、24 文件清单及工具/构建条件。使用现有独占临时库、无外网本地合成通道,不接生产或 live。
|
||||||
|
2. 优先复用可核验的现有构建和 runner;先检查源码绑定及资源归属。前提已清理或无法核实时按现有隔离流程重建,不冒称旧构建属于当前候选。
|
||||||
|
3. 只预定一条代表性合同用例,1 worker、零重试、trace=on,原超时和业务断言不变。观察首次 bootstrap 周边的会话标记、navigator.onLine、离线快照可用性及 refresh 调用入口;不同时再启全套或追加重试。
|
||||||
|
4. 仅输出布尔值、函数名、相对时序、路径/状态及摘要,不输出身份、credential 或存储内容。如需观测注入,只能在独占实验副本中添加观测,不改真实工作树、状态判定或 mock 返回;记录副本差异,不冒充未修改候选的普通门禁。
|
||||||
|
5. 若一次观测仍不能区分入口或条件,保留未知并报告最小后续实验,不追加运行。首次问题取得证据后,再追踪非 manual spec 的 helper、TEST_IDS 和 route 注册,产出场景清单及拟写入清单。
|
||||||
|
6. 此阶段不要求整条用例绿:认证前置仍失败如实报告;若越过前置而停在旧“更多”,也只报告该进展。原 trace、截图、日志和派生索引分列,清理失败不倒写为自动通过。
|
||||||
|
|
||||||
|
本阶段不修改真实工作树中的业务或测试源文件,不开展文件外 80 条的独立修复,不实现门禁。静态新发现仅是候选,不构成写入授权。
|
||||||
|
|
||||||
|
### 3.1 本轮观测结果与边界
|
||||||
|
|
||||||
|
证据目录为 artifacts/qa-flow/e2e-auth-preconditions/phase0-20260907-03/。source-before.json 绑定 HEAD=66f25b1、dirty 源码摘要及获准 21 文件;不是仅用 commit 冒充带工作树差异的候选。来源快照共 1052 文件(client 436、server 522、scripts 79、Trellis 15),收尾逐项核对未变。构建在独占临时副本中完成,未覆盖 client/dist;观测副本的差异单独保留。
|
||||||
|
|
||||||
|
| 首次入口 | sessionHint | navigator.onLine | 可用离线快照 |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| mount-effect | false | false | 此调用未读取 |
|
||||||
|
| bootstrap-entry | false | false | false |
|
||||||
|
| bootstrap-primary-refresh | false | false | false |
|
||||||
|
| runRefresh-entry | false | false | 此调用未读取 |
|
||||||
|
|
||||||
|
网络依次为 GET /login 200(请求无会话标记)、POST /api/auth/refresh 200(请求无标记)、GET /api/me 200(请求有标记);全程没有 /api/auth/login 请求。这证明本轮是“无提示 + 离线 + 无快照”没有命中 AuthContext.tsx:365/:370 的两个早退条件,进入 bootstrap 主 refresh 分支,再被成功 mock 恢复身份。不是登录前已观察到 cookie,不是业务断言通过。
|
||||||
|
|
||||||
|
- 观测只添加一个日志 helper 和 11 个调用;去除这些节点后 AST 与原 AuthContext 完全一致,回执位于 phase0-20260907-01/observation-ast-check.json。未改条件、返回值、mock 或原测试源码。
|
||||||
|
- 后续还有第二组 mount/bootstrap 日志,但实际网络 refresh 只有一次;不把函数日志重复当成网络重试,也不无证据归因 StrictMode。
|
||||||
|
- 本轮只在 loopback/无外网隔离环境实际观测到 online=false。未做网络环境的单变量对照,不宣称 unshare 必然导致该值;旧 trace 的 online 值仍未观测,不能倒填。修复目标仍是夹具状态合同,不是强行将 navigator.onLine 改成 true。
|
||||||
|
- 唯一实际执行的原用例为 payment-reviewer-permissions.spec.ts:380,选择标题“合同只读人员看不到新增编辑续约和归档动作”,workers=1、trace=on、retries=0。原始结果 1 timedOut / retry 0 / 216617ms;错误仍指向 login-identifier 的 locator.fill,续约/归档断言没有到达。
|
||||||
|
- 原始 Playwright JSON、trace.zip、observation-result.json 及静态清单分别保留和哈希;trace SHA-256 为 fc1bb04629f8dcba772959db1534ec1a24ffa2dee7a67c9def97275428150f00。观测副本回执固定无发布资格,harness exit 2 不表示测试通过。
|
||||||
|
|
||||||
|
两次准备错误不能隐去,也不能算作浏览器重试:phase0-20260907-01 缺 QA_DIAGNOSTIC_PWA_ROOT,在启动 Playwright 前退出;phase0-20260907-02 的锚定 grep 未匹配 qualified title,收集 0 条并报 No tests found。两者实际浏览器用例均 0,原错误及分类保留。03 改用已验证的无锚点标题选择器,先 --list 确认恰好 1 条,再执行唯一一次浏览器用例。未重试任何业务断言。
|
||||||
|
|
||||||
|
资源按各次 private 归属记录定点核验:3 个独占容器和 3 个临时副本目录均已不存在,未遍历或操作生产容器。01/03 有独立的剩余库计数 0;02 只有原阶段 cleanupExit=0,没有单独计数文件,不补造数字。最终来源/资源回执为 closeout-receipt-v2.json;首版校验错误地要求每次都有计数文件而返回 false,原件保留,修正版明确区分证据类型。
|
||||||
|
|
||||||
|
### 3.2 静态分母与历史迁移清单(暂缓,不是缺陷数)
|
||||||
|
|
||||||
|
下表及 static-census.json 保留阶段 0 的静态标签和提案来源。在线对照已证明代表性用例在原生在线时无需改变 mock 即可完成登录与会话恢复,因此“成功 refresh 与表单共存”本身不足以认定内在矛盾。执行端撤回默认迁移 31 文件的建议;原件不覆盖,最新结论以 §6.1 为准。
|
||||||
|
|
||||||
|
static-census.json 从文件系统枚举当前 65 个非 manual spec,追踪静态 import/export、局部函数、场景/钩子调用、route 和 TEST_IDS;33 个 spec 直接出现 refresh 路由。依赖闭包记录 42 个非 spec 模块,本地 import 无未解析项,未发现动态 import/require,依赖模块内未发现 refresh 路由或间接 route 注册。函数调用索引只是审阅导航,不是任意 JavaScript 数据流的完备证明;条件分支、动态拼接和将来新增文件仍需审查,不把“未命中”写成运行通过。
|
||||||
|
|
||||||
|
| 分类 | 文件数 | 本次提案 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| 成功 refresh 与驱动登录表单存在同场景矛盾 | 30(原 23 + 新 7) | 仅迁移矛盾合成路径,保留原表单及业务断言 |
|
||||||
|
| 成功 refresh 与访客提示页存在矛盾 | 1 | 单列 wecom-first-bind,不并入“30 个填表单”口径 |
|
||||||
|
| 状态合同正确 / 显式已认证起点 | 2 | local-candidate-witnesses、PWA 不迁移 |
|
||||||
|
| 恢复建模缺项,非相同成功身份恢复 | 2 | user-onboarding、visual-portal 延后核对,不列入拟写入清单 |
|
||||||
|
| 仅业务 mock / 访客供应商入口 mock | 2 | leave-team-calendar、wecom-entry 不迁移 |
|
||||||
|
| spec 及静态依赖没有 route 注册 | 28 | 保留原本后端、live 入口或纯源码断言,不宣称正常或授权运行 live |
|
||||||
|
|
||||||
|
以下路径均位于 client/tests/e2e/。表中列出需改的认证处理器与表单入口坐标;完整场景/钩子、函数调用及依赖锚点见 static-census.json。默认方案是保持现有登录 helper,guest 起步,成功登录后才允许 refresh 和 /me 恢复该场景身份,不批量改成默认管理员或直接跳过登录。行号以当前源码摘要为准。
|
||||||
|
|
||||||
|
| spec | refresh 处理器行 | 入口/场景锚点 | 来源及局部边界 |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| biz8-ap-ledger-project.spec.ts | 105 | 202/208/217 | 原 23;仅合成认证路径 |
|
||||||
|
| contract-detail-workspace.spec.ts | 123 | 232/234/246 | 原 23;不改详情业务断言 |
|
||||||
|
| dg7-mobile-information-dedupe.spec.ts | 501 | 753/760/898 | 原 23;保留按场景角色 |
|
||||||
|
| internal-readiness-ui.spec.ts | 163 | 297/301/318 | 原 23 |
|
||||||
|
| login-portal-ux.spec.ts | 81 | mockPasswordLogin:33 / Portal:554 / prepareEmployeePortal:628 | 原 23 的混合文件;仅该 helper 的表单调用链 |
|
||||||
|
| mobile-approvals-offline.spec.ts | 291 | 第三场景:184 / 表单:322 | 原 23;不动前两条真实 API 场景及离线语义 |
|
||||||
|
| payment-reviewer-permissions.spec.ts | 194 | 341/343/384 | 原 23;旧“更多”及续约/归档仍归门禁阶段 B |
|
||||||
|
| pc-core-workflow-visual-wave2.spec.ts | 148 | 306/315/307 | 原 23 |
|
||||||
|
| pc-detail-mobile-visual-wave3.spec.ts | 679 | 1217/1219/1233 | 原 23 |
|
||||||
|
| pc-finance-admin-visual-wave4.spec.ts | 489 | 1001/1004/1041 | 原 23 |
|
||||||
|
| r100-design-baseline.spec.ts | 66 | 188/190/252 | 原 23 |
|
||||||
|
| r101-mobile-wip-closeout.spec.ts | 134 | 319/321/368 | 原 23 |
|
||||||
|
| r102-reimbursement-main-flow.spec.ts | 148 | 346/348/357 | 原 23;不改“编辑”相关业务断言 |
|
||||||
|
| r103-cross-page-ui-consistency.spec.ts | 318 | 609/611/688 | 原 23 |
|
||||||
|
| r111-invoice-reimbursement-guard.spec.ts | 310 | 681/687/799 | 原 23 |
|
||||||
|
| r124-mobile-entry-matrix.spec.ts | 168 | 425/432/492 | 原 23 |
|
||||||
|
| r125-invoice-reupload-after-delete.spec.ts | 190 | 355/361/383 | 原 23 |
|
||||||
|
| r5-real-device-feedback-mobile-ux.spec.ts | 75 | 243/249/365 | 原 23 |
|
||||||
|
| r6-mobile-responsive-system-hotfix.spec.ts | 90 | 415/421/534 | 原 23 |
|
||||||
|
| r6-mobile-unified-design-rollout.spec.ts | 143 | 492/498/623 | 原 23 |
|
||||||
|
| r6-wecom-mobile-rendering-hardening.spec.ts | 101 | 363/375/523 | 原 23 |
|
||||||
|
| r89-mobile-login-navigation.spec.ts | 223 | 438/440/471 | 原 23;保留真实登录导航意图 |
|
||||||
|
| visual-shell.spec.ts | 87 | 340/343/365 | 原 23 |
|
||||||
|
| announcements-policy-ack.spec.ts | 148(fulfillJson:29 默认 200) | 282/293/303 → helpers/auth.ts:96 | 新 7;保留登录后 currentUser 切换 |
|
||||||
|
| global-search.spec.ts | 46/48 | 180/208/228/248 → helpers/auth.ts:96 | 新 7 |
|
||||||
|
| leave-flow.spec.ts | 132(fulfillJson:16 默认 200) | 302/317 → helpers/auth.ts:96 | 新 7;保留 activeUser 选择及注销 |
|
||||||
|
| r92-mobile-invoice-usability.spec.ts | 53(fulfillJson:10 默认 200) | 286(TEST_IDS)/300/319/345 | 新 7;间接 testid 命中 |
|
||||||
|
| system-action-confirmation.spec.ts | 338/340 | 615 起 → helpers/auth.ts:96 | 新 7 |
|
||||||
|
| workflow-action-confirm-ui.spec.ts | 150/152 | 301 起 → helpers/auth.ts:96 | 新 7 |
|
||||||
|
| workflow-quick-approve.spec.ts | 97/99 | 218 → helpers/auth.ts:96 | 新 7 |
|
||||||
|
| wecom-first-bind.spec.ts | 60/62,me:74 | 180/181 | 新增访客提示路径,不填表单;固定 guest |
|
||||||
|
|
||||||
|
wecom-first-bind 的成功 refresh 和 /me 会满足 GuestOnly(client/src/router/guards.tsx:48)的重定向条件;/login 的 wrapper(client/src/router/index.tsx:103)没有 wecom query 例外。它与待看见的 login-wecom-notice 有静态前置矛盾,但本轮没有用新运行给其旧失败定因。
|
||||||
|
|
||||||
|
保留与延后项具体合同:
|
||||||
|
|
||||||
|
- login-portal-ux 的 mockGuestAuthChrome 访客场景、邮件验证码及找回密码场景保留;:776 的显式会话提示 + refresh 首次 500 后 200 + 直接 /portal 是产品 bootstrap 恢复回归,不替换成永久 401,也不把产品内部恢复重试等同于 Playwright retry。只迁移 mockPasswordLogin 所服务的表单路径。
|
||||||
|
- mobile-approvals-offline 只处理第三场景内的合成认证;PWA 的 :509 显式 addCookies 和 :516 直接 /portal 属于合法已认证起点,不迁移,不改 Service Worker 或专用输入供给。
|
||||||
|
- user-onboarding 只 mock login 和 /me,未 mock refresh,不能计入无条件成功 refresh;visual-portal 的全 API fallback 在 :185 返回 200/空 data,不含恢复身份的 accessToken,也不能并入同一类。两者只是静态可见的恢复建模缺项,另列待核对,不借本次范围顺手修复。
|
||||||
|
- 28 个无 route 文件逐个登记 import、helper、TEST_IDS 及场景/钩子。business-detail-routing、interaction-pattern-unification、management-navigation-contract、reimbursement-content-consistency 是不依赖浏览器登录的源码/纯函数断言;其余保留现有真实后端或受环境开关控制的入口,未授权开启 live。
|
||||||
|
- 原 23 文件的 133 条观测(127 失败、6 通过)及文件外 80 条保持历史口径。新 7/访客提示/延后项没有从 80 中扣除,也没有把 207 转成已归因的产品缺陷数。
|
||||||
|
|
||||||
|
## 4. 后续批准边界
|
||||||
|
|
||||||
|
- 阶段 1:阶段 0 结论、精确清单及 helper 接口单独获批后,先补状态合同回归,再实施最小迁移;保留正常访客、恢复会话和真实 API 样本。
|
||||||
|
- 阶段 2:按届时批准的固定矩阵验证,零重试和默认全套并发不变;定向认证前置与整套诊断结果分列。全套需完整前提、资源归属和独立回执;中断不补造状态、不自动重跑。
|
||||||
|
- 认证前置解释清楚后,文件外 80 条和新增红项再单列同类候选、独立问题、前置阻断或证据不足。仅再获批清单可写,不承诺清空所有失败。
|
||||||
|
- 本任务负责认证前置;release-gate-integrity 阶段 B 仍负责合同详情入口和续约/归档断言。机制推进遵循原任务批准范围,本轮不启动其他阶段 A 内容。
|
||||||
|
|
||||||
|
### 4.1 阶段 1 原接口与写入提案(已暂缓,非推荐默认路径)
|
||||||
|
|
||||||
|
拟新增 client/tests/e2e/helpers/syntheticAuth.ts 和 client/tests/e2e/synthetic-auth-contract.spec.ts;连同 §3.2 的 31 个现有 spec,共 33 个代码/测试文件。仅当前任务的 PRD/设计/执行记录随结果更新;不改已有门禁 21 文件、产品源码、helpers/auth.ts、配置、依赖或发布入口。新增合同 spec 放在非 manual 集合内,不借新增测试缩减原 65 文件分母。
|
||||||
|
|
||||||
|
helper 采用每次安装独立的闭包状态,不用模块级可变会话或共享 storageState:
|
||||||
|
|
||||||
|
1. createSyntheticAuthSession({ initialState }) 必须显式指定 guest 或 authenticated。本次 30 个表单矛盾路径使用 guest,wecom-first-bind 的提示场景也保持 guest;已有正确的 authenticated/PWA/恢复场景不迁移。
|
||||||
|
2. loginSucceeded() 只在场景原有的登录身份选择和成功判定之后切为 authenticated;logout() 清为 guest。原有角色选择、计数、失败注入和响应数据继续由场景提供,helper 不默认赋角色、不存储或输出凭据。
|
||||||
|
3. refresh 与 /me 通过同一闭包的认证检查:guest 返回既有 AUTH_001/401 结构且不种会话提示;authenticated 调用场景提供的成功响应函数。登录成功保留会话提示,注销清除提示,随后 full navigation 可恢复或保持未认证。refresh 不是永久 401。
|
||||||
|
4. 接入现有 route 分支;拆开 login/refresh 共用成功分支,不额外注册能被 catch-all 覆盖的竞争处理器。选择性 route 的 login-portal-ux 仍保留原优先级和 :776 自有恢复处理器;不得覆盖该场景。
|
||||||
|
5. 新合同 spec 先覆盖状态隔离、登录前拒绝、成功登录后 refresh、失败登录不认证、注销后 refresh 拒绝及显式 authenticated;再按获批矩阵验证真实导航/表单/恢复。沿用现有 Playwright,不新引入单测框架,不修改 navigator.onLine 凑绿。
|
||||||
|
|
||||||
|
推荐下一批先批准这份 31+2 清单和接口,再实施;浏览器矩阵另批。针对性建议选新合同 spec、合同权限、间接 shared login、角色切换、login-portal-ux 的访客/Portal/恢复、wecom-first-bind 六类边界,固定每条次数、零重试、trace=on。新合同的纯状态断言不启动浏览器;需要浏览器的观测仍应逐条写清授权。后续全套诊断必须绑定迁移后摘要,默认并发不变,不把局部 PASS 当整套结果。
|
||||||
|
|
||||||
|
## 5. 验收、回滚及风险
|
||||||
|
|
||||||
|
- AC1/AC2 先验收观测与范围,AC3/AC4 后验收获批实施,AC5/AC6 保持剩余问题及发布边界。阶段 0 完成不等于任务完成。
|
||||||
|
- 普通 full-local 全绿耗时及稳定性仍未知;旧 197 分钟和中断运行不进入发布成本估算。本任务完成不启用 R1。
|
||||||
|
- 回滚仅涉及本任务以后获准的差异,不回退他人或门禁任务已批准改动。提交、push、归档及部署各自授权。
|
||||||
|
- 防止把文件内共现误当场景关系,或把恢复会话永久改成 401:使用场景清单、四类状态合同和正确样本,不以重试或弱化断言收口。
|
||||||
|
|
||||||
|
## 6. 已批准的在线对照(2026-09-07,仅实验,不迁移)
|
||||||
|
|
||||||
|
- 用户批准阶段 0,暂缓阶段 1,仅授权一次在线定向实验。复用原合同单条用例和观测构建,在相同隔离、数据、mock、断言及零重试条件下比较认证前置;不运行整个合同文件的其他用例、不启动全套。
|
||||||
|
- 网络隔离实际存在于证据目录中的 run-isolated.sh(unshare -Urn)与 run-inner.sh,不在用户列出的受管 runner 内;不能因此推断宿主机本身离线,也不能将外层包装条件漏记。数据库容器继续 network=none,仅使用本轮独占 Unix socket。
|
||||||
|
- 唯一拟改变的启动前提:在本轮独占网络命名空间内增加一对 up 的 veth 及文档保留地址,不接宿主网卡、不配默认路由、不开放公网。不修改 navigator.onLine,也不通过 CDP 强制在线来替代原生测量。
|
||||||
|
- 业务用例启动前使用空白页读取原生 online,必须为 true,否则停止、不运行用例。同一浏览器的两个独立 context 中,仅对其中一个 setOffline(true),验证另一个仍 online=true;关闭后再创建新 context,验证在线状态及合成 cookie 隔离。此项是无业务请求的前置检查,结束并关闭浏览器后才运行原用例;不能外推为全仓自定义 fixture 已完全排除泄漏。
|
||||||
|
- 正式用例固定 payment-reviewer-permissions.spec.ts:380 的原标题,workers=1、retries=0、trace=on;先 --list 确认恰好一条。仍用未改变条件的观测副本,记录实际用例首个 bootstrap 的 online/hint/快照值及 refresh/login 顺序,不只信前置探针。
|
||||||
|
- 判据按阶段拆分:在线时是否命中 guest-ready、出现 login 请求并越过登录前置;原整条用例最终结果另列。已知旧“更多”断言仍可能超时,不能把该下游红项判成认证实验失败;同样,一条认证前置通过不能证明其余 30 文件均无需修改。阶段 1 的方向仍由用户按结果决定。
|
||||||
|
- 旧 trace 中登录成功不单独证明当时没有 refresh 或 online=true,历史未观测条件继续保留未知。实验原件、候选/构建摘要、外层脚本差异、context 探针及资源清理分别留痕;不修改产品、测试源或旧 21 文件。
|
||||||
|
|
||||||
|
### 6.1 在线对照结果(已获用户复核认可)
|
||||||
|
|
||||||
|
证据目录:artifacts/qa-flow/e2e-auth-preconditions/online-20260907-01/。本轮只运行一次原合同用例;prepare.mjs、用例选择、mock、产品判定、断言及观测副本均与阶段 0 相同,1052 份来源文件和 114 份观测构建文件摘要一致。外层差异在 wrapper.diff:仅在独占命名空间内增加 up 的 veth 对及保留地址,并追加在线/context 前置检查和本次授权标签。没有默认路由、宿主外网接口或 navigator 属性改写;原生 online=true 不等于公网可达,也不是一次普通发布绿路径运行。
|
||||||
|
|
||||||
|
| 实际用例首个 bootstrap | 阶段 0 离线对照 | 本轮在线对照 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| sessionHint | false | false |
|
||||||
|
| navigator.onLine | false | true |
|
||||||
|
| 可用离线快照 | false | false |
|
||||||
|
| 入口 | bootstrap-primary-refresh | bootstrap-guest-ready |
|
||||||
|
| 登录请求前 refresh 数 | 1,且没有登录请求 | 0 |
|
||||||
|
| /api/auth/login | 未调用 | 1 次,200 |
|
||||||
|
| 登录/合同前置 | 登录表单等待超时 | 通过,到达旧“更多” |
|
||||||
|
| 整条结果 | timedOut / retry 0 | timedOut / retry 0 |
|
||||||
|
|
||||||
|
本轮实际网络顺序为 GET /login → POST /api/auth/login → GET /api/me → GET /contracts-registry → POST /api/auth/refresh → GET /api/me。首个文档及 login 请求不带会话标记;标记出现在登录后。第二次完整文档导航才通过 refresh 恢复身份,这正是该 mock 在在线条件下被真实使用的会话恢复路径,不是应当永久禁止的请求。
|
||||||
|
|
||||||
|
trace 中 sourceLine 387/388/389/390/396 的断言均完成且无错误:合同 URL、标题、新增/编辑不可见及合同行可见;:397 的“更多”点击超时。整条原始结果为 1 timedOut / retry 0 / 214570ms,commandExit=1,harness exit=2 / PARTIAL,无发布资格。续约、归档仍未到达,不计入权限验收通过,也不在本轮修改。
|
||||||
|
|
||||||
|
原生 online 与 context 隔离前置结果:两个新 context 初始均 true;第一个 setOffline(true) 后该 context 为 false,第二个仍 true;关闭后新 context 仍 true,合成探针 cookie 没有泄漏。检查只使用空白页,不执行额外业务用例。network-preflight.json 的 externalRequests=0 是探针未主动发起外部导航的声明,不是浏览器后台请求的仪表计数;无外网边界由独立命名空间及无外连路由维持。不能据此宣称全套所有自定义 fixture 已排除状态复用。
|
||||||
|
|
||||||
|
原始全套诊断的隔离也有明确出处:artifacts/qa-flow/release-gate-integrity/diagnostic-run-20260906-01/run-isolated.sh:43 调 unshare -Urn,:45 只启 loopback。它处于受管 runner 外层;仅搜索 full-local-diagnostic/run-web-gates 看不到这层包装,并不能归因宿主机网络常态。本轮不观测宿主真实网络,也不倒填该旧运行的 navigator 值。
|
||||||
|
|
||||||
|
结论与下一项:
|
||||||
|
|
||||||
|
- 对这条代表性合同用例,改变原生在线启动条件即可越过认证前置,无需改它的认证 mock;这足以否定“必须先批量迁移 31 文件才能恢复它”的判断。
|
||||||
|
- 一条用例不能证明全部 30/31 文件均无需修改,也不能凭完整用例仍红就判迁移必要。127/207/80 的旧统计保持不变,没有重新分配或扣减。
|
||||||
|
- 原 31+2 方案暂缓,不再作为默认建议。下一项建议先定环境启动合同:普通在线验收在实际 context 入口验证 online;有意置离线的场景必须保留自己的语义。此处只提后续方向,尚未实现、未授予门禁或外层环境修改权限。
|
||||||
|
- 长期规则暂存当前任务,不修改受冻结的模块 spec 或门禁 21 文件;待修复对象与范围获批后再将可复现的执行合同沉淀到对应规约。
|
||||||
|
|
||||||
|
closeout-receipt.json 已核对:原 21 文件及 1052 来源文件未变、114 构建文件相同,启动后实验脚本摘要未变;原 cleanupExit=0、剩余独占库计数 0,本轮容器和临时副本按归属定点确认不存在。原始 trace SHA-256:069f15ae266f052898ed41853a56e135ce1e2cc5b1149dc956244694a431ab96。无提交、push、归档、部署或生产操作,场景 8、经理缺口和 R1 继续挂起。
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
# E2E 认证前置统一 — 执行与批准清单
|
||||||
|
|
||||||
|
## 当前状态
|
||||||
|
|
||||||
|
- in_progress / inline。创建轮使用 task.py create --no-start;用户随后明确批准阶段 0,已 task start 切换到本任务,不授予阶段 1 批量修改权限。
|
||||||
|
- 门禁任务获准 21 文件逐字节未动;HEAD=66f25b1,本地 origin/main=492920c。新任务独立、非子任务,未转移合同阶段 B 的业务验收责任。
|
||||||
|
- 创建轮只读已有 single trace;随后在阶段 0 授权内实际执行一次原合同用例的观测实验,结果 timedOut,未改真实源码。新现场条件与旧 trace 严格分开,见 design.md §1/§3.1。
|
||||||
|
- 两个 manifest 保持为空,符合 inline 合同;受影响规约按步骤读取指定章节,不将超出注入上限的大文件登记成可完整自动注入的上下文。未来若切 sub-agent,必须另行准备真实、适量的上下文,空清单不兼容该模式。
|
||||||
|
|
||||||
|
## 规划检查
|
||||||
|
|
||||||
|
- [x] 记录独立立项、认证状态合同及 24/23/80 的口径边界。
|
||||||
|
- [x] 核实请求、fulfill 与 /me 顺序,不预设 cookie 污染。
|
||||||
|
- [x] PRD、设计、执行清单分开;PRD 按最终结构收敛,无 TBD 或重复开放的已答事实。
|
||||||
|
- [x] 运行上下文、治理、敏感内容及新增文件 whitespace 检查,核对旧 21 文件摘要未变。
|
||||||
|
- [x] 用户批准阶段 0,已 task start;仅执行该阶段。
|
||||||
|
|
||||||
|
## 阶段 0(已批准,2026-09-07)
|
||||||
|
|
||||||
|
- [x] 读取任务及受影响规约,冻结候选、原回执及原件摘要。
|
||||||
|
- [x] 按 design.md §3 核验或重建独占本地前提,留资源归属,不接生产、live 或真实身份。
|
||||||
|
- [x] 一次单条、1 worker、零重试、trace=on,保持原断言;观测副本差异和实际命令单列,真实候选不动。
|
||||||
|
- [x] 记录 cookie、online、离线快照和调用入口及缺项;不倒填历史、不自动追加实验。
|
||||||
|
- [x] 静态追踪 helper/TEST_IDS/route,交场景分类及拟写入清单,不开始迁移。
|
||||||
|
- [x] 准备 AC1/AC2、清理结果及阶段 1 方案交审;不是独立复核通过。文件外 80 条不逐项展开独立问题。
|
||||||
|
|
||||||
|
## 后续阶段(尚未批准)
|
||||||
|
|
||||||
|
- [ ] 清单和 helper 接口获批后,补状态合同回归并最小迁移。
|
||||||
|
- [ ] 保留业务断言及正确样本,记录是否越过认证前置;不修旧“更多”或产品权限缺口。
|
||||||
|
- [ ] 按固定矩阵验证,完整/中断/未运行状态及候选绑定分列,不重试至绿或冒充整套。
|
||||||
|
- [ ] 对剩余失败单独归类;新增红项不自动修。
|
||||||
|
- [ ] 主会话检查后提交独立复核,不自行签独立通过。
|
||||||
|
- [ ] 提交、push、归档、部署和 R1 启用均等待各自授权。
|
||||||
|
|
||||||
|
## 规划验证记录
|
||||||
|
|
||||||
|
以下是创建轮历史记录,当轮不运行产品测试、构建、数据库或浏览器;不用于描述随后已获批的阶段 0 实验。
|
||||||
|
|
||||||
|
- python3 .trellis/scripts/task.py validate .trellis/tasks/09-07-e2e-auth-preconditions:两个 inline manifest 均 0 entries,通过。
|
||||||
|
- node scripts/qa/check-trellis-governance.mjs --json:PASS,0 errors / 0 warnings。
|
||||||
|
- node scripts/qa/check-sensitive-content.mjs --json:PASS,0 findings。
|
||||||
|
- git diff --check 及六个新增任务文件分别执行 git diff --no-index --check:均通过;旧获准 21 文件逐项 SHA-256 一致。
|
||||||
|
- 首轮规划校验的 Scope/Test Plan 缺项已补齐;超出注入上限的整份模块文档没有继续登记在 inline 清单中。首轮日志保留于 artifacts/qa-flow/e2e-auth-preconditions/planning-20260907-01/,复验位于 validated/,最终交审快照与回执位于 final/;不覆盖旧门禁回执。
|
||||||
|
- 以上仅主会话文档验证,不是阶段 0 已执行、实施获批或独立复核通过。
|
||||||
|
|
||||||
|
## 阶段 0 运行记录
|
||||||
|
|
||||||
|
已收到阶段 0 的明确批准。仅在独占实验副本内为 AuthContext 添加安全观测,真实测试及应用源码保持不变;使用本地隔离库和无外网命名空间,不运行全套,不实施迁移。
|
||||||
|
|
||||||
|
| 证据目录后缀 | 实际浏览器用例 | 结果与限制 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| phase0-20260907-01 | 0 | 缺 QA_DIAGNOSTIC_PWA_ROOT,Playwright 前准备失败;观测副本构建及 AST 校验保留 |
|
||||||
|
| phase0-20260907-02 | 0 | 锚定标题没有匹配 qualified title,No tests found;原始错误保留,不算浏览器重试 |
|
||||||
|
| phase0-20260907-03 | 1 | 先 --list 确认一条原用例,再 workers=1 / retries=0 / trace=on;1 timedOut,仍在登录前置 |
|
||||||
|
|
||||||
|
- 源码绑定:HEAD=66f25b1、local origin/main=492920c,观测前 sourceDigest=b7c8edbe8c3c4005e8dead6cc57aa50a8722bf515f6663e4be8a013aa728cd5a。两次后续准备核对源摘要及构建文件摘要后复用观测构建,不重做产品构建、不覆盖 client/dist。
|
||||||
|
- 观测结果:首次 sessionHint=false / online=false / offlineSnapshotAvailable=false,入口 bootstrap-primary-refresh → runRefresh;实际网络 refresh 一次,login 零次。没有将本轮浏览器状态倒填旧 trace,也没有把重复函数日志算作网络重试。
|
||||||
|
- 原始用例耗时 216617ms、retry 0,错误仍为 login-identifier 的 locator.fill;该耗时不是普通 full-local 成本、不是通过证据。
|
||||||
|
- 依赖盘点:65 个非 manual spec,33 文件有直接 refresh 路由;30 个表单矛盾文件 + 1 访客提示矛盾文件。31 个现有 spec + 2 个新增 helper/合同 spec 是阶段 1 提案,不是写入授权。另两项恢复建模缺口分开延后,原 80 条文件外失败不重新计数。
|
||||||
|
- 回执位于 artifacts/qa-flow/e2e-auth-preconditions/phase0-20260907-03/。原始报告、trace、observation-result.json、static-census.json 各自保留;收尾 source/resource 核验见 closeout-receipt-v2.json。首版核验因误设“每次都有独立剩余库计数文件”失败,保留 closeout-receipt.json,不补造 02 的计数。
|
||||||
|
- 清理边界:3 个本轮容器及 3 个临时副本已定点确认不存在;01/03 的原计数为 0,02 原 cleanupExit=0 而无单独计数文件。检查没有修改资源或触碰生产。
|
||||||
|
|
||||||
|
## 阶段 0 交审检查
|
||||||
|
|
||||||
|
- [x] 再核对原 21 文件、1052 份运行来源文件及 HEAD/origin 引用未变;closeout-receipt-v2.json 的 valid=true。
|
||||||
|
- [x] 上下文(两个 inline manifest 均 0 entries)、治理(0 errors / 0 warnings)、敏感内容(0 findings)、tracked/new-task whitespace 检查完成。仅主会话检查,不代替独立复核。
|
||||||
|
- [x] 用户独立复核并批准阶段 0;不等于批准阶段 1 的 31+2 清单和接口。
|
||||||
|
|
||||||
|
阶段 0 已独立复核通过,阶段 1 暂缓;后续在线对照另行交审。没有提交、push、归档或部署。场景 8、经理缺口和 R1 均继续挂起。
|
||||||
|
|
||||||
|
文档检查原件位于 phase0-20260907-03/review/。首轮 whitespace shell 把 git diff --no-index 的“存在文件差异”退出 1 当作格式失败,实际诊断为空;whitespace-v2.json 保留逐文件退出码及空诊断,未为消除该状态改动内容。最终交审使用相对 planning-20260907-01/final/ 六文件快照的增量;回执不得把旧门禁 21 文件或临时观测副本算作本次新增实现。
|
||||||
|
|
||||||
|
## 在线对照(已批准,2026-09-07)
|
||||||
|
|
||||||
|
- [x] 冻结阶段 0 回执、原 21 文件和来源快照;在独占命名空间内准备原生 online=true 前提,记录外层包装差异。
|
||||||
|
- [x] 完成空白页在线与 context 隔离前置检查;实际均符合预期,不伪改 navigator。
|
||||||
|
- [x] 一次原合同单条、零重试、trace=on:认证及合同前置通过;旧“更多”点击超时,整条非 PASS。
|
||||||
|
- [x] 校验实际 trace 的 online、hint、调用入口及请求顺序,核验资源清理及来源不变,准备交审。
|
||||||
|
- [x] 用户认可本次在线结果,下一步先审环境启动合同;原 31+2 迁移不作为默认建议,不自动执行。
|
||||||
|
|
||||||
|
仅此在线实验获批;阶段 1 暂缓,场景 8、经理缺口和 R1 不变,无生产、提交、push、归档或部署授权。
|
||||||
|
|
||||||
|
## 在线运行回执
|
||||||
|
|
||||||
|
最新后续状态:环境合同规划归 release-gate-integrity 的 R2/R6、设计 §10;本轮仅修改两个任务的规划/事实文档和追加撤销资格侧记,不实现、不重跑、不修合同、不改产品或测试源。207 原浏览器清单从真实红项、工作量和 R1 等决策输入中撤销,raw JSON/trace/包装脚本不删除、不覆盖,其他原始证据按自己的范围保留。认证任务保持 in_progress,仅等待后续任务处置,不自行提交、归档或宣称阶段 1 完成。
|
||||||
|
|
||||||
|
- 实际命令沿用原选择器:npm run test:e2e:full -- tests/e2e/payment-reviewer-permissions.spec.ts --grep '合同只读人员看不到新增编辑续约和归档动作' --workers=1 --trace=on --retries=0 --reporter=list,json,html。先 --list 确认一条,没有额外业务重跑。
|
||||||
|
- 实际首个 bootstrap:online=true / sessionHint=false / offlineSnapshotAvailable=false,命中 guest-ready;登录前 refresh=0、login=1。登录后 full navigation 的 refresh 成功是保留的正常恢复路径。
|
||||||
|
- 387/388/389/390/396 的合同前置断言通过;397“更多”超时。1 timedOut / retry 0 / 214570ms;下游续约和归档未覆盖,不冒充整条通过或 R1 成本。
|
||||||
|
- 来源、观测构建和原 21 文件逐项未变;本轮容器及临时目录均确认已清理,原独占库剩余计数 0。详见 online-20260907-01/closeout-receipt.json,valid=true。
|
||||||
|
- 运行脚本、原始报告、trace、前置探针与派生结果各自保存,未覆盖阶段 0 原件。原 static-census.json 的“矛盾”标签保留为历史静态分类,不再当作已证明需修改的缺陷。
|
||||||
|
- 本次只更新当前任务事实和忽略目录证据,不改受冻结规约或任何产品/测试源码;执行端撤回默认迁移 31 文件的建议,等待用户决定环境合同优先的后续范围。
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
# E2E 认证前置统一
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
先确定合成浏览器验收的运行前提与认证起点,再决定修正环境合同还是认证夹具;不预设需要批量迁移 spec。覆盖登录、会话恢复和注销的真实边界,任务独立于 release-gate-integrity,不以修复全部浏览器红项或启用发布门禁作为完成条件。
|
||||||
|
|
||||||
|
## Confirmed Background
|
||||||
|
|
||||||
|
- 用户同意另立任务及认证状态规则;创建轮只做规划,随后明确批准阶段 0 的一次本地观测及静态依赖盘点,不授予批量修改权限。使用 inline,不派 implement/check 代理。
|
||||||
|
- 已有 24 文件字面交集中,22 文件合并 login/refresh 无条件返回成功,login-portal-ux 另有混合场景;共 23 文件含矛盾路径。local-candidate-witnesses 的有状态处理器不属于此类。24 不是传递依赖扫描所得的全仓上限。
|
||||||
|
- 原完整诊断中,这 23 文件对应 133 条结果(127 失败、6 通过),文件外另有 80 条失败。这是观测及文件交集,不是逐条确证的同根因清单。来源:artifacts/qa-flow/release-gate-integrity/auth-refresh-readonly-20260907-01/inventory.json。
|
||||||
|
- 代表性合同用例在单条 1 worker 和全套 4 workers 中都卡登录前置。单条 trace 的首文档和 refresh 请求均未带会话 cookie,后续才出现带标记的 mock fulfill 和 /me 请求。“谁在 /login 前种下 cookie”不能作为已成立的前提;原始证据与限制见 design.md §1。
|
||||||
|
- AuthContext.tsx:370 的条件还取决于 navigator.onLine;无会话提示不意味着必定跳过 refresh。旧 trace 没有记录该浏览器值或证明首次 refresh 的调用入口,仍不得倒填历史条件。
|
||||||
|
- 阶段 0 新现场已记录:首次 bootstrap 的 sessionHint=false、online=false、offlineSnapshotAvailable=false,经 bootstrap-primary-refresh → runRefresh 发出一次网络 refresh;无 login 请求,原合同用例仍在登录表单前置 timedOut。仅实验副本追加观测,未改真实源码或判定条件。详见 design.md §3.1。
|
||||||
|
- 静态盘点覆盖当前 65 个非 manual spec 及本地 import/export 依赖:30 文件存在成功 refresh 与表单路径共存(原 23 + 新 7),另 1 文件为访客提示页路径。原“矛盾”标签只表示条件性风险候选,不能直接当成内在缺陷或迁移必要性。另 2 个认证恢复建模缺项继续分开列示。
|
||||||
|
- 已批准的在线对照已完成:相同源码、mock 和 114 份观测构建文件,实际首个 bootstrap 的 online=true、hint=false、无快照,进入 guest-ready;登录前 refresh=0、login=1,登录及合同前置断言通过。整条用例仍为 1 timedOut,停在旧“更多”按钮,续约/归档未到达。执行端撤回默认迁移 31 文件的建议,详见 design.md §6.1。
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
阶段 0 已独立复核批准;后续单条在线对照已执行,当前交审。阶段 1 的原 31+2 清单及接口保留为历史提案,暂缓且不再作为默认下一步。环境启动合同或夹具改动、后续运行矩阵均须重新明确范围并批准;本次在线授权已用完,不追加运行。
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
以下 R1–R5 为原阶段 1 设计约束,不表示已经确诊 31 文件必须修改。在线对照后,修复对象及范围仍待决定;只有本轮取证与边界约束生效,不启动迁移或环境门禁实现。
|
||||||
|
|
||||||
|
### R1 — 显式认证状态
|
||||||
|
|
||||||
|
- 驱动表单的场景以未认证状态开始;显式登录前 refresh 返回未认证,不能凭固定成功 mock 恢复身份。
|
||||||
|
- 登录成功后允许 refresh 恢复会话,注销后恢复未认证;不能把 refresh 永久设为 401。
|
||||||
|
- 权限投影、视觉及业务流可显式从已认证状态开始,但不再重复驱动表单;保留导航、刷新、/me 和原业务断言。
|
||||||
|
- 正确访客、有状态和真实后端登录场景不得被无差别替换。参照 client/tests/e2e/local-candidate-witnesses.spec.ts:199、:241、:252、:260。
|
||||||
|
|
||||||
|
### R2 — 触发条件先于修复
|
||||||
|
|
||||||
|
- 阶段 0 仅在获批本地合成环境观察会话标记存在性、navigator.onLine、离线快照可用性及首次 refresh 调用入口,不采集 credential、身份或存储原文。
|
||||||
|
- 已有 trace、新实验和源码推论分别标注;不把新观测倒写成旧现场,不预设 cookie 污染或离线环境问题。
|
||||||
|
- 观测不改变产品认证语义、不改写网络状态凑通过,也不具有发布资格。阶段 0 运行授权独立于任务创建授权。
|
||||||
|
|
||||||
|
### R3 — 场景级范围
|
||||||
|
|
||||||
|
- 在已有 24 文件清单基础上追踪共享 helper、TEST_IDS、route 注册和调用路径,登记场景起点、refresh 行为、登录方式及证据锚点。
|
||||||
|
- 以场景而非整文件决定迁移。阶段 1 的精确写入清单须单独获批;新发现同类文件不自动进入写入范围。
|
||||||
|
- 文件外 80 条本轮不继续归因。已知认证前置解释清楚后,再单列同类候选、独立问题、前置阻断和证据不足;不将它们整体纳入修复承诺。
|
||||||
|
|
||||||
|
### R4 — 保留验证意图
|
||||||
|
|
||||||
|
- 不放宽业务、权限、导航和会话恢复断言;不增加 retry、缩减集合、移入 manual、开启 live 或降低全局并发来制造通过。
|
||||||
|
- 零重试保持;单 worker 定向证据与默认 4 workers 全套诊断分列。重复运行事先固定目的和次数,不重试至绿。
|
||||||
|
- 认证前置恢复后暴露的业务失败只报告。合同“更多”漂移、详情入口及续约/归档断言仍由门禁任务阶段 B 处理,不自动视为通过。
|
||||||
|
|
||||||
|
### R5 — 完成不等于发布
|
||||||
|
|
||||||
|
- 本任务交付认证夹具合同、获批迁移、针对性验证和剩余失败分类,不要求无关红项清零。
|
||||||
|
- 不修改发布入口、R1/R2/R3 机制、skip 或回执消费。R1 启用仍需红项处置、普通 full-local 全绿实测成本、可复现性证据及单独批准。
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
|
||||||
|
- [x] AC1(R2):阶段 0 给出来源绑定的条件观测或明确缺项;区分请求 cookie、mock 调用和未观测的浏览器状态,不预设 cookie 污染。阶段 0 已获用户独立复核批准;后续在线对照另行交审。
|
||||||
|
- [ ] AC2(R3):形成包括间接 helper 的场景清单及冻结写入范围;保留原 24/23 口径与新增发现差异,不覆盖旧回执。静态清单已复核,31+2 迁移暂缓,不能把候选清单当成最终写入授权。
|
||||||
|
- [ ] AC3(R1):获批夹具覆盖登录前未认证、登录后恢复、注销后未认证及显式已认证起点;正常访客和真实后端场景不被误迁移。
|
||||||
|
- [ ] AC4(R4):命令及 trace 绑定候选和实际用例集合,零重试、原集合及业务断言不变;认证前置到达下一阶段有可核对证据,不冒称整条用例通过。
|
||||||
|
- [ ] AC5(R3/R4):后续诊断保留剩余失败分类、失败位置及未覆盖状态;合同后续断言、场景 8 和其他问题没有夹带修复。
|
||||||
|
- [ ] AC6(R5):交审 diff 与获批范围一致;主会话验证不代替独立复核,完成不授予 R1 启用、提交、push、归档或部署资格。
|
||||||
|
|
||||||
|
## Out Of Scope
|
||||||
|
|
||||||
|
产品认证或权限逻辑、经理及付款主体数据、场景 8、合同业务入口修复、发布门禁机制及启用、真实账号和生产数据、live/公网测试、完整绿路径成本测量及未经批准的其他浏览器红项修复。
|
||||||
|
|
||||||
|
## Test Plan
|
||||||
|
|
||||||
|
阶段 0 实际只执行一条原合同用例,1 worker、零重试、trace=on,结果 timedOut;两次准备/收集错误均执行 0 条浏览器用例,分列保留。静态盘点及源码/资源/文档验证不增加浏览器运行。后续实施拟验证四类认证状态及原业务断言,针对性矩阵与全套诊断须各自批准;不把未运行或中断结果补成通过。
|
||||||
|
|
||||||
|
后续另批的在线对照也只执行一次相同原用例,1 worker、零重试、trace=on;空白页原生 online/context 隔离检查通过,实际用例 trace 再次确认 online=true。认证前置通过与下游“更多”超时分别计入回执,不记为整条 PASS,不用于普通全绿成本。
|
||||||
|
|
||||||
|
## Approval And Next Decision
|
||||||
|
|
||||||
|
- 已批准:独立立项方向、认证状态合同及范围边界。
|
||||||
|
- 创建轮已做:planning task、已有 trace 核对和方案;未运行实验。
|
||||||
|
- 最新批准(2026-09-07):用户批准 design.md §3 的阶段 0,已 task start;仅一次本地定向启动条件取证及静态盘点。阶段 1 的迁移清单和运行矩阵仍待后续批准。
|
||||||
|
- 上轮交审:阶段 0 结果及阶段 1 的 31+2 文件/接口提案;该提案随后暂缓,未实施。
|
||||||
|
- 后续批准(2026-09-07):阶段 0 已经用户独立复核批准;阶段 1 暂缓,仅批准一次确认原生 navigator.onLine=true 的本地合同定向实验,零重试、trace=on。当前状态仍为 in_progress,不是 planning;已有清单不构成迁移授权。
|
||||||
|
- 当前交审:在线对照及来源/资源回执。建议下一项先审环境启动前提与显式 offline 用例的边界,不继续原 31 文件默认迁移;这不是环境修复授权。场景 8、经理缺口和 R1 不变。
|
||||||
|
- 最新结论(2026-09-07):用户认可在线对照及撤回默认迁移。207 原浏览器清单整体撤销真实红项/工作量/R1 等决策资格,原件保留,不能倒写成逐条均已证明假失败。环境合同归 release-gate-integrity 的 R2/R6 与设计 §10,本 task 不重复定义实现合同;31+2 方案继续暂缓,阶段 B 仅保留原合同业务范围。当前仅规划交审,无实施或运行授权扩展。
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"id": "e2e-auth-preconditions",
|
||||||
|
"name": "e2e-auth-preconditions",
|
||||||
|
"title": "E2E 认证前置统一",
|
||||||
|
"description": "阶段 0 及在线对照已获用户复核认可;31+2 迁移暂缓。207 原浏览器清单撤销决策资格且原件保留;环境合同规划归 release-gate-integrity R2/R6 与设计 §10,本任务保留取证,不实施或重跑。",
|
||||||
|
"status": "in_progress",
|
||||||
|
"dispatch_mode": "inline",
|
||||||
|
"dev_type": "frontend",
|
||||||
|
"scope": null,
|
||||||
|
"package": null,
|
||||||
|
"priority": "P1",
|
||||||
|
"creator": "shunli",
|
||||||
|
"assignee": "shunli",
|
||||||
|
"createdAt": "2026-09-07",
|
||||||
|
"completedAt": null,
|
||||||
|
"branch": "main",
|
||||||
|
"base_branch": "main",
|
||||||
|
"worktree_path": null,
|
||||||
|
"commit": null,
|
||||||
|
"pr_url": null,
|
||||||
|
"subtasks": [],
|
||||||
|
"children": [],
|
||||||
|
"parent": null,
|
||||||
|
"relatedFiles": [
|
||||||
|
"client/tests/e2e/payment-reviewer-permissions.spec.ts",
|
||||||
|
"client/tests/e2e/local-candidate-witnesses.spec.ts",
|
||||||
|
"client/tests/e2e/login-portal-ux.spec.ts",
|
||||||
|
"client/tests/e2e/helpers/auth.ts",
|
||||||
|
"client/src/auth/AuthContext.tsx",
|
||||||
|
".trellis/tasks/09-06-release-gate-integrity/prd.md"
|
||||||
|
],
|
||||||
|
"notes": "最新处置:用户已复核认可在线对照,207 原浏览器清单撤销决策资格;环境合同仅在 release-gate-integrity R2/R6 与 §10 规划交审,31+2 暂缓,本轮不实现或运行。以下保留在线交审时的历史说明:2026-09-07 阶段 0 已获用户独立复核批准;保持 in_progress / inline,不是 planning。另批在线对照仅一次原合同单条,零重试、trace=on:首个 bootstrap online=true/hint=false/无快照,guest-ready,登录前 refresh=0/login=1;登录后的整页导航正常恢复会话。整条 1 timedOut 卡旧更多按钮,续约/归档未覆盖。独占命名空间内 veth 提供原生在线信号,无外连默认路由或 navigator 覆写;context 离线及探针 cookie 隔离检查通过。原 21 文件、1052 来源及 114 构建文件摘要一致,资源已按归属清理。30+1 是条件性候选,不是已确诊内在缺陷;31+2 方案暂缓,执行端撤回默认迁移建议,等待本次复核及后续范围批准。relatedFiles 不授予写入权限;场景 8、经理缺口、R1 不变。未委派、提交、push、归档、部署或接触生产。",
|
||||||
|
"meta": {}
|
||||||
|
}
|
||||||
@@ -224,3 +224,19 @@ git diff --check
|
|||||||
## 2026-09-09 提交与推送授权
|
## 2026-09-09 提交与推送授权
|
||||||
|
|
||||||
用户对“AP 与付款修复分两笔提交并推送,不部署、不执行真实恢复、不混入后续准备文档”明确回复“是”。本次只提交本 task 对应已隔离交审文件及当前授权记录;原恢复 task、错误豁免后续阶段和另外两个未跟踪 task 不进入这两笔。实际提交 SHA 与远端结果以 Git 回执为准,不提前宣称 push 成功;生产仍未部署,业务验收状态不随提交改变。
|
用户对“AP 与付款修复分两笔提交并推送,不部署、不执行真实恢复、不混入后续准备文档”明确回复“是”。本次只提交本 task 对应已隔离交审文件及当前授权记录;原恢复 task、错误豁免后续阶段和另外两个未跟踪 task 不进入这两笔。实际提交 SHA 与远端结果以 Git 回执为准,不提前宣称 push 成功;生产仍未部署,业务验收状态不随提交改变。
|
||||||
|
## 已按本候选例外完成部署(2026-09-09)
|
||||||
|
|
||||||
|
用户明确批准 b87cc55 的例外、existing 发布及必要旧应用回滚,不授权自动数据库恢复。14:07 CST 既有 deploy-existing.sh 返回 0:build-init、run-init、build-server、build-switch-server 均 PASS;随后迁移对账、就绪/依赖/runtime smoke、公网构建标识及前端 bundle 检查和受控备份合同 refresh 完成。没有使用未发布 override,没有执行回滚。独立 clone main=origin/main=b87cc55 是本次发布来源,主工作树仍保留原未提交治理改动,不据主工作树旧 HEAD 判断生产版本。
|
||||||
|
|
||||||
|
部署后复核:
|
||||||
|
- 正式运行 build=b87cc55aca0003130cf8a5bbe38d0dd15528389c;14:08 CST 单独公网 /ready 与首页 HTTP 200,/ready buildSha=b87cc55aca00。
|
||||||
|
- init 日志的阶段精确为 validate_config → migrate → check_required_configuration,INIT_PASS/existing,无 seed 阶段;发布前后迁移对账无 pending。
|
||||||
|
- 运行容器内权限常量、AP 路由、workspaceSettings、auth 插件及 deploy-init 五文件摘要与候选完全一致。直接调用运行镜像中的权限解析器:manager/ceo 不获 finance.ledger.view,finance/finance_mgr 及兼财务角色可读,admin 通配保留;manager/ceo 的 expense.approve 和 payment.batch.review 保留。
|
||||||
|
- 上一项是部署制品字节核验和运行时代码策略执行,不是使用真人会话请求 AP 接口或实际点击菜单。本轮没有伪造真人 token、登录真实账户或读取台账明细;authenticated account route test / real-user page acceptance 均 NOT_RUN,不冒充四项真人验收全通过。
|
||||||
|
- 系统已发布且公网可测试,但经理/CEO 仍可经既有报销列表查看全部报销的开口保留,本轮仅收窄 AP,不宣称“经理只能看所有相关单据”整体实现。
|
||||||
|
- 发布后可用空间 45.50 GiB;旧备份、独立旧镜像制品及 34 个 Docker 拒绝删除项仍保留,未追加清理。backup unit BUILD_SHA 已刷新为新版本;最新已验备份仍是发布前 f223bfb,不把合同刷新写作新版本备份已产出。
|
||||||
|
- 例外缺口仍保留:完整候选验收没有通过证据;本次真实镜像构建现已通过,不能继续列为未构建;附件与应用恢复尚未演练,镜像回滚不撤销数据库写入。数据库最小恢复历史成功不等于任意当前备份均已演练恢复。
|
||||||
|
|
||||||
|
证据归 artifacts/qa-flow/20260909-release-b87cc55/:deployment-result.json、postcheck-result.json、public-check.json、脱敏迁移回执;完整发布输出为受控 0600 日志,不回传原始环境/业务内容。主会话执行发布及验证,不伪称独立 reviewer 验证部署集成。此次状态补记未另行提交或推送,不归档整个门禁 task,不启动 R1/阶段 B 或修 58 条。
|
||||||
|
|
||||||
|
下一步回到业务验收:majianyong 本人确认 AP 台账入口不可用、原审批/付款复核入口可用;财务本人确认 AP 可读和已复核批次可下载银行制单。仅让用户验证自己的授权界面,不代付、不代批、不创建额外测试付款。实际付款仍是复核 → 制单 → 网银付款 → 回单登记,下载成功不等于付款成功。取得真人交接证据后按已排队的统一待办任务收敛下一阶段方案,不让等待验收自动变成另起一笔未批准功能改动。
|
||||||
|
|||||||
@@ -48,6 +48,18 @@
|
|||||||
|
|
||||||
## 审批边界
|
## 审批边界
|
||||||
|
|
||||||
|
### 新候选发布准备草案(提交后,未授权部署)
|
||||||
|
|
||||||
|
- 候选固定为 b87cc55aca0003130cf8a5bbe38d0dd15528389c,已推远端。执行来源为干净的 seed-preflight-integration 副本,不使用仍在旧基线且有其他治理差异的主工作树。此前候选和例外不自动转移。
|
||||||
|
- 本地已有证据:已审两包、顺序补丁集成与 110/110 定向回归。尚无完整镜像构建或完整候选门禁通过证据;不将定向回归冒充普通发布资格,不自动启动暂停的 R1、阶段 B 或修复 58 条红项。
|
||||||
|
- 下一步申请本候选的一次生产只读预检:运行版本/镜像身份、候选迁移集合与数据库迁移状态、三类 enabled/active 最低配置计数、磁盘余量、最近备份时效及已有回滚制品元数据。只输出脱敏摘要;不读取个人访问历史、单据明细或银行信息,不执行 migrate/seed,不写配置,不切容器。现有审批记录不替代本轮明确边界。
|
||||||
|
- 预检必须执行已修的状态解析逻辑;如远端仍为旧脚本,应先设计获准的调用方式,不以“只读”名义自行上传或安装文件。读取受限则标未验证,不绕权限。
|
||||||
|
- 回滚目标以本轮确认的生产运行版本为准,不默认仍是历史 f223bfb。旧镜像必须保持独立可用;备份完整性与恢复能力分别记录。已知 DB 最小恢复成功不代表附件或应用恢复成功,也不证明新备份已恢复演练;不沿用历史“从未成功”的过期结论。
|
||||||
|
- 若最低配置缺失,报告管理员,不自动 seed/启用配置。existing 仍会执行迁移,配置检查失败可能发生在迁移落库之后,镜像回滚不能撤销数据变化;任何数据恢复还涉及恢复点之后业务数据的处置,另行审批。
|
||||||
|
- 汇总本轮证据后再提交发布决定:普通路径需要完整候选验收;若仍未具备,明确列出缺口与回滚验收,用户对本 SHA 单独批准例外和部署。未获批准不执行真实发布,不拿旧例外填空。
|
||||||
|
- 部署获批后按既有 existing 路径执行,检查日志无 seed 阶段、版本/健康一致;AP 验收覆盖仅 ceo/manager 拒绝、finance/finance_mgr 可读、兼财务多角色可读、审批/复核入口保留。真人制单/付款流程由授权人员验收,下载不等于付款;不代操作真实银行业务。
|
||||||
|
- 失败停止并报告,不自动扩大写入或恢复范围;成功也不删除独立回滚制品。磁盘治理、恢复附件/应用验证、统一待办和错误豁免期限沿原任务处理,不混进本次发布写入。
|
||||||
|
|
||||||
用户已同意本 task 规划方向;以上统一入口、直接调用显式模式和三类非空硬门禁为本轮收敛的待审实施方案。获批前保持 planning;不把此前“好的”解释成批准尚未呈现的兼容变化。实施只在独立工作树,不叠加未提交的治理修复。提交、推送、生产部署另批。
|
用户已同意本 task 规划方向;以上统一入口、直接调用显式模式和三类非空硬门禁为本轮收敛的待审实施方案。获批前保持 planning;不把此前“好的”解释成批准尚未呈现的兼容变化。实施只在独立工作树,不叠加未提交的治理修复。提交、推送、生产部署另批。
|
||||||
|
|
||||||
后续授权与实施:用户对收敛方案明确回复“是”,已进入独立工作树实施。共享入口为 server/src/scripts/deploy-init.js。只读检查通过 Prisma repeatable-read 事务显式 SET TRANSACTION READ ONLY;费用类型没有专用管理页面,改为提示管理员核对既有 /api/expense-types,缺失数据另批修复,不新增 UI。
|
后续授权与实施:用户对收敛方案明确回复“是”,已进入独立工作树实施。共享入口为 server/src/scripts/deploy-init.js。只读检查通过 Prisma repeatable-read 事务显式 SET TRANSACTION READ ONLY;费用类型没有专用管理页面,改为提示管理员核对既有 /api/expense-types,缺失数据另批修复,不新增 UI。
|
||||||
|
|||||||
@@ -82,3 +82,79 @@
|
|||||||
- 预检缺陷定性是“该拦时可能拦不住”,未证明生产曾误放行。独立审查在其环境较大输出触发 141,但约 64KB 不是通用安全阈值;此前已有短输出捕获 producer=141/consumer=0 的记录,调度和管道实现都会影响触发,不采纳“日常绝不会触发”的推断。
|
- 预检缺陷定性是“该拦时可能拦不住”,未证明生产曾误放行。独立审查在其环境较大输出触发 141,但约 64KB 不是通用安全阈值;此前已有短输出捕获 producer=141/consumer=0 的记录,调度和管道实现都会影响触发,不采纳“日常绝不会触发”的推断。
|
||||||
|
|
||||||
两笔提交准备顺序:先 preflight(门禁 task 三文档、预检脚本、测试及 spec 对应增量),再 seed(原 17 文件范围,包含 F1/F2 手册补充和 seed task 最新状态;spec 只取 seed 增量)。共享 spec 第二笔以第一笔结果为基线。提交、推送、完整候选门禁与部署均未因此授权;当前只做隔离集成和定向验证。
|
两笔提交准备顺序:先 preflight(门禁 task 三文档、预检脚本、测试及 spec 对应增量),再 seed(原 17 文件范围,包含 F1/F2 手册补充和 seed task 最新状态;spec 只取 seed 增量)。共享 spec 第二笔以第一笔结果为基线。提交、推送、完整候选门禁与部署均未因此授权;当前只做隔离集成和定向验证。
|
||||||
|
## 本轮提交推送回执
|
||||||
|
|
||||||
|
用户明确授权按清单两笔提交并推送,不含部署。已在隔离集成副本完成:
|
||||||
|
- 81102c2:迁移预检修复,6 文件,归 09-06-release-gate-integrity。
|
||||||
|
- b87cc55aca0003130cf8a5bbe38d0dd15528389c:日常发布与首次初始化分离,17 文件,归 09-09-existing-deploy-seed-separation。
|
||||||
|
逐笔暂存内容按已批准补丁、路径集合和文件摘要核验;没有纳入其他治理改动。推送后 fetch 回读:集成副本 HEAD = origin/main = b87cc55,副本工作树干净。原冻结包保留;未新建分支、未归档 task、未部署或查询生产。
|
||||||
|
主工作树仍在 b918530,保留原有未提交治理差异及任务状态补记,没有强行快进覆盖它们。后续候选检查必须在隔离集成副本或新建干净候选副本执行,不能用主工作树 HEAD 冒充新候选。
|
||||||
|
验证沿用同字节输入的集成 110/110;源码包独立复核通过,集成由主会话验证,完整候选门禁尚未执行。当前段落为提交后的本地回执,不倒改提交前冻结材料;不为状态补记另造第三笔提交。下一步按 seed design 的新候选发布准备草案核对前置,生产只读预检与部署不在本次 Git 授权内。
|
||||||
|
## 新候选生产只读预检回执(2026-09-09)
|
||||||
|
|
||||||
|
用户在提交推送后批准本候选只读预检。本次在内存经 SSH stdin 执行已提交的新预检脚本,没有上传安装、修改远端文件、执行 migrate/seed、切换容器或业务写入。执行脚本摘要 2386ac545d8d12595c61fbcdb5e807746965a36ce539170cc6118f3eb6f15d2e,与 b87cc55 候选一致;原始身份字段只在内存传递,输出为既有脱敏摘要。
|
||||||
|
|
||||||
|
观测时间 2026-09-09 12:54 CST:
|
||||||
|
- 候选 b87cc55;生产运行 build f223bfb72fb2baef51199702c2def84c41af7aef,容器运行中且检查前后身份/启动时间不变。Docker 未提供 Health 状态,未据此声明公网健康通过。
|
||||||
|
- 目标/数据库身份及迁移对账 PASS,无待执行迁移。脚本 rollbackWindow=OPEN 仅是既有 terminated 状态计数检查,不是备份可恢复或完整回滚演练结论。
|
||||||
|
- 三类最低配置在明确 READ ONLY 事务内读取:启用费用类型 39、启用审批规则 3、活动报销流程 1,全部满足本候选最低非空门禁;没有读取员工或业务明细。
|
||||||
|
- 数据/附件/回滚制品所在文件系统可用 8.32 GiB、使用率 85.9%。不能据此单独保证镜像构建和备份峰值空间够用,未清理任何文件。
|
||||||
|
- 最新备份状态文件 ACCESS_DENIED,不能确认其完成时间、制品身份或摘要。备份 service 最后退出时间为本日 02:30:53 CST、Result=success/exit=0;这只是服务元数据,不能替代备份验真,不绕权限升级读取。
|
||||||
|
- 独立旧镜像文件仍存在,匹配当前生产 build/image,大小 1117595648 字节与旧 receipt 一致;只核元数据,未重算 archive SHA-256、未 docker load 或恢复测试,不把旧 receipt 中的摘要冒充本轮实测。
|
||||||
|
|
||||||
|
证据入口:artifacts/qa-flow/20260909-b87cc55-readonly/,含只读脚本、preflight-result.json、metadata-result.json 与脱敏 migration 输出。候选副本仍干净,未提交额外代码、未推送、未部署。当前仅完成只读预检,不产生发布资格。
|
||||||
|
|
||||||
|
下一步:先通过获准管理员读取路径补最新备份的时效/manifest/数据库包和附件包完整性验证;在发布前另外核算构建峰值空间、确认回滚制品验收范围。读权限缺口不以自动 sudo、切 root 或宣称服务成功代替。材料齐后对本 SHA 明列完整候选门禁未通过等缺口,再请用户决定例外及部署;当前不建议直接发布。不重复要求已完成的数据库最小恢复演练,也不把它扩为附件/应用恢复成功。
|
||||||
|
## 获准 root 通道备份验真与空间盘点(2026-09-09)
|
||||||
|
|
||||||
|
用户明确允许 hyinda-root 执行只读备份验真,并询问发布空间及旧部署内容清理。本轮经该既有 SSH 身份内存执行检查;未自动 sudo、上传安装、恢复数据、删除文件或部署。已有管理员备份校验脚本沿用严格的 f223bfb/build/image 约束,未放宽失败条件。
|
||||||
|
|
||||||
|
最新备份 PASS_INTEGRITY_ONLY:完成于 2026-09-09 02:30:53 CST,检查时约 10.48 小时;manifest 摘要、数据库 dump 和附件归档大小/摘要全部一致。验证的是当前备份完整性,本轮未恢复;此前 DB 最小恢复成功不因此扩为附件或应用恢复成功。
|
||||||
|
|
||||||
|
磁盘约 58.94 GiB,可用 8.32 GiB,使用率 85.9%,可用 inode 1400857。Docker system df:Images 39.54GB、标称可回收 39.24GB;停止容器标称约 190MB;构建缓存约 268MB。目录 allocated 统计:日志约 1.019 GiB、独立回滚制品约 1.041 GiB、自动备份 0.132 GiB、数据库 0.092 GiB、附件 0.018 GiB、部署仓库 0.028 GiB;目录可能重叠,不相加。Docker store 的 du 超时记 NOT_MEASURED,不当作零占用。image ls -a 含中间镜像,与 system df 汇总计数口径不同,不相加或冒充同一分母。
|
||||||
|
|
||||||
|
已生成只读清理候选清单:845 个创建至少 7 天、无 tag/digest、未被任何运行或停止容器引用且排除已固定生产回滚镜像的镜像。清单 SHA256=30d78bac23658f70453e5cc8a6d2e9c943c32c0ab48227e605efa3abb8e6438e。共享层与中间镜像依赖使实际可释放字节未知,不能承诺释放 Docker 标称全部 39.24GB。这是候选清单,不是用户已授权删除。
|
||||||
|
|
||||||
|
建议先做这批精确清单的受控清理,不直接部署:8.32 GiB 不能证明构建峰值够用,候选 server/package.json 变化会失效 server_deps 的依赖安装缓存。若用户另批清理,每项删除前必须重新核对年龄/标签/digest/容器引用/受保护镜像;引用变化、存在后继依赖或条件不符则跳过报告,不强制删除。不执行 system prune -a/--volumes,不删除任何容器、卷、数据库、附件、备份、独立回滚制品或带标签镜像。清理前后核对运行镜像/启动时间及磁盘,剩余空间再用于发布预算判断;未达余量不扩大清理范围。
|
||||||
|
|
||||||
|
证据位于 artifacts/qa-flow/20260909-b87cc55-readonly/:backup-integrity-result.json、disk-inventory-result.json、image-cleanup-candidates-result.json 及本轮只读脚本。下一步请用户批准上述精确范围的删除;本轮只读授权不包含清理或部署。原备份 ACCESS_DENIED 已由本次获准 root 完整性检查补齐,不能继续写作验不了。
|
||||||
|
## 已授权镜像清理结果(2026-09-09)
|
||||||
|
|
||||||
|
用户对“仅清理已列明 845 项、逐项复核、不强删、不动容器/卷/业务数据/备份/回滚制品”回复“是”,本轮据此执行。没有将权限扩大为全局 prune、删除带标签镜像或部署。
|
||||||
|
|
||||||
|
通过获准 hyinda-root 的 SSH stdin 执行本地检查脚本,未远端安装脚本。每项操作前复核全部容器 ID/镜像/状态/启动时间不变,重新检查镜像无 tag/digest、年龄至少七天、与冻结创建时间一致,排除所有容器引用和已固定回滚镜像。唯一删除命令为 docker image rm --no-prune <完整批准ID>,不用 force;--no-prune 防止隐式继续删除清单外父镜像。Docker 拒绝的依赖项保留,不改依赖关系、不重新扩大范围。
|
||||||
|
|
||||||
|
2026-09-09 13:11 CST 结束:
|
||||||
|
- 845 个批准 ID 全部逐项处理,811 删除成功,34 SKIPPED_DOCKER_REFUSED;本地逐事件核对 ID 集合与批准清单完全相等,无重复或额外项。
|
||||||
|
- 可用空间 8.32 → 46.43 GiB,净增加 38.11 GiB。此为文件系统实测净变化,不是把镜像虚拟大小相加。空间薄余量问题本次已解除,不继续清理备份或回滚制品来凑空间;具体构建峰值仍未实测,不承诺任意后续构建永不耗尽。
|
||||||
|
- 全部运行/停止容器的 ID、镜像、状态、启动时间在清理前后保持一致;Docker volume 名单不变,没有执行容器/卷删除或业务数据写入。
|
||||||
|
- 独立回滚归档在清理前后完整 SHA256 都与原保存回执匹配,本轮已重新验摘要;没有 docker load/恢复演练,不能把此写成恢复成功。
|
||||||
|
- 真实生产版本未切换,未部署、未提交额外代码、未推送,未删除任何备份或审计日志。
|
||||||
|
|
||||||
|
证据:artifacts/qa-flow/20260909-b87cc55-readonly/cleanup-result.json、cleanup-execution-events.jsonl、cleanup-approved-images.py。脚本 SHA256=748c2d11e92ed5373969418410bfd83a5cc86fe16f3099e683879b75311a6895;原批准清单 SHA256=30d78bac23658f70453e5cc8a6d2e9c943c32c0ab48227e605efa3abb8e6438e。34 项保留不是重新索要强删授权的理由。
|
||||||
|
|
||||||
|
### 下一步:新候选发布审批,不再追加空间清理
|
||||||
|
|
||||||
|
候选仍是 b87cc55。已有:独立源码复核、集成 110/110、本候选生产身份/迁移只读预检(无 pending)、39/3/1 最低配置、最新备份 manifest/数据库/附件完整性、独立旧镜像完整性及 46.43 GiB 余量。生产仍处于旧候选,Git 推送和清理授权均不是部署授权。
|
||||||
|
尚缺完整候选门禁通过;真实候选镜像尚未构建,附件/应用恢复未演练。原数据库最小恢复已成功,不能继续表述为“从未成功恢复”;镜像回滚不能撤销迁移等数据库写入,恢复备份会影响恢复点后的数据。应据这些明确缺口对本 SHA 提交发布例外及部署审批,获批后才执行 existing 发布与版本/健康/AP权限验收;不沿用旧 AP 候选的例外授权。直到该批准到来,保留原回滚制品、34 个被拒绝镜像及业务数据不动。
|
||||||
|
## 本候选例外与部署授权
|
||||||
|
|
||||||
|
用户对明确列出的 b87cc55 发布例外、existing 部署及必要的旧版本应用回滚回复“是”。接受完整候选验收未通过/真实镜像尚未构建/附件与应用恢复未演练;不授权自动数据库恢复或删除回滚制品。本次使用远端 main 的干净克隆作为发布源(原集成副本 detached 不满足 upstream 门禁,不设置未发布 override);固定 b87cc55,来源检查 published/remoteVerified=true。Trellis start 写入本克隆 task branch 元数据后,已只恢复该自动改动到候选原字节,保留会话指针;未改变候选代码或新建功能分支。
|
||||||
|
|
||||||
|
执行证据归 artifacts/qa-flow/20260909-release-b87cc55/。沿既有 deploy-existing.sh 调用链,固定 existing/SYNC_ENV=0,使用原受控 refresh 身份,不运行初始化 seed;任何失败停止,应用是否已切换以阶段与运行版本实测为准。准备阶段尚不代表部署成功。
|
||||||
|
## 已按本候选例外完成部署(2026-09-09)
|
||||||
|
|
||||||
|
用户明确批准 b87cc55 的例外、existing 发布及必要旧应用回滚,不授权自动数据库恢复。14:07 CST 既有 deploy-existing.sh 返回 0:build-init、run-init、build-server、build-switch-server 均 PASS;随后迁移对账、就绪/依赖/runtime smoke、公网构建标识及前端 bundle 检查和受控备份合同 refresh 完成。没有使用未发布 override,没有执行回滚。独立 clone main=origin/main=b87cc55 是本次发布来源,主工作树仍保留原未提交治理改动,不据主工作树旧 HEAD 判断生产版本。
|
||||||
|
|
||||||
|
部署后复核:
|
||||||
|
- 正式运行 build=b87cc55aca0003130cf8a5bbe38d0dd15528389c;14:08 CST 单独公网 /ready 与首页 HTTP 200,/ready buildSha=b87cc55aca00。
|
||||||
|
- init 日志的阶段精确为 validate_config → migrate → check_required_configuration,INIT_PASS/existing,无 seed 阶段;发布前后迁移对账无 pending。
|
||||||
|
- 运行容器内权限常量、AP 路由、workspaceSettings、auth 插件及 deploy-init 五文件摘要与候选完全一致。直接调用运行镜像中的权限解析器:manager/ceo 不获 finance.ledger.view,finance/finance_mgr 及兼财务角色可读,admin 通配保留;manager/ceo 的 expense.approve 和 payment.batch.review 保留。
|
||||||
|
- 上一项是部署制品字节核验和运行时代码策略执行,不是使用真人会话请求 AP 接口或实际点击菜单。本轮没有伪造真人 token、登录真实账户或读取台账明细;authenticated account route test / real-user page acceptance 均 NOT_RUN,不冒充四项真人验收全通过。
|
||||||
|
- 系统已发布且公网可测试,但经理/CEO 仍可经既有报销列表查看全部报销的开口保留,本轮仅收窄 AP,不宣称“经理只能看所有相关单据”整体实现。
|
||||||
|
- 发布后可用空间 45.50 GiB;旧备份、独立旧镜像制品及 34 个 Docker 拒绝删除项仍保留,未追加清理。backup unit BUILD_SHA 已刷新为新版本;最新已验备份仍是发布前 f223bfb,不把合同刷新写作新版本备份已产出。
|
||||||
|
- 例外缺口仍保留:完整候选验收没有通过证据;本次真实镜像构建现已通过,不能继续列为未构建;附件与应用恢复尚未演练,镜像回滚不撤销数据库写入。数据库最小恢复历史成功不等于任意当前备份均已演练恢复。
|
||||||
|
|
||||||
|
证据归 artifacts/qa-flow/20260909-release-b87cc55/:deployment-result.json、postcheck-result.json、public-check.json、脱敏迁移回执;完整发布输出为受控 0600 日志,不回传原始环境/业务内容。主会话执行发布及验证,不伪称独立 reviewer 验证部署集成。此次状态补记未另行提交或推送,不归档整个门禁 task,不启动 R1/阶段 B 或修 58 条。
|
||||||
|
|
||||||
|
下一步回到业务验收:majianyong 本人确认 AP 台账入口不可用、原审批/付款复核入口可用;财务本人确认 AP 可读和已复核批次可下载银行制单。仅让用户验证自己的授权界面,不代付、不代批、不创建额外测试付款。实际付款仍是复核 → 制单 → 网银付款 → 回单登记,下载成功不等于付款成功。取得真人交接证据后按已排队的统一待办任务收敛下一阶段方案,不让等待验收自动变成另起一笔未批准功能改动。
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
# 设计与依据
|
||||||
|
|
||||||
|
## 官方依据
|
||||||
|
|
||||||
|
- 已安装 CLI:0.6.16。本轮使用随附指南,不声称已核对在线最新版本。
|
||||||
|
- `.agents/skills/trellis-meta/references/local-architecture/task-system.md`:active task 为会话级状态,官方 start/current/finish 管理,不依赖旧全局 .current-task。
|
||||||
|
- `.agents/skills/trellis-meta/references/local-architecture/context-injection.md`:workflow-state 从当前状态选块;收到的上一轮注入不代替切换后的读取。
|
||||||
|
- `.agents/skills/trellis-meta/references/customize-local/overview.md`:先 current --source,最小修改项目文件,不编辑全局 npm 缓存。
|
||||||
|
|
||||||
|
## 根因与修复
|
||||||
|
|
||||||
|
实际恢复 task 与当时 current 返回的付款 task 不一致;官方会话解析正常,不能将旧 .current-task 不存在诊断为运行时损坏。工作迁移到隔离副本后,也未把相应命令的 cwd 和 task 核验作为固定入口。
|
||||||
|
|
||||||
|
采用既有 project-governance 记录完整合同,start/continue/before-dev/check/finish 各加短检查。工作范围或 cwd 变化时,从实际执行根目录读取 current --source;获批任务不匹配则用 start 显式切换并回读 task/phase。没有稳定身份时报告降级,不手写共享指针,不以 CLI 退出 0 代替回读成功。
|
||||||
|
|
||||||
|
验证始终在实际修改副本运行。主工作树 phase 和隔离副本验证分别记录;不把副本更新称为已集成。finish 清空会话指针与 archive 完成任务不同,未获授权不归档。保持 inline,无需开启子代理或改 hooks。
|
||||||
|
|
||||||
|
这是 AI 执行合同修复,不宣称新增了自动强制拦截。真正下一轮平台注入需观察下一轮消息;本轮可验证官方读取和渲染结果。
|
||||||
|
|
||||||
|
## 回退
|
||||||
|
|
||||||
|
仅撤销本 task 的治理文本差异;会话指针若要恢复,使用官方 start 明确选择下一项已获批工作。不改其他任务的验收或状态,不删除既有未跟踪目录。
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
# 执行清单
|
||||||
|
|
||||||
|
- [x] 读取随附官方指南、CLI 版本和当前任务来源,确认不是会话解析故障。
|
||||||
|
- [x] 公布最小方案,建立本任务合同;不扩业务或部署范围。
|
||||||
|
- [x] 官方 start 激活本 task,回读 current 和 phase。
|
||||||
|
- [x] 同步治理 spec、相关五个 skill 及既有交付事实源。
|
||||||
|
- [x] 临时 fixture 验证会话隔离与任务切换;验证实际修改根目录和本轮 diff。
|
||||||
|
- [x] 记录本地验证、独立复核、平台下一轮注入及提交状态。
|
||||||
|
|
||||||
|
## 验证命令
|
||||||
|
|
||||||
|
- `python3 .trellis/scripts/task.py current --source`
|
||||||
|
- `python3 .trellis/scripts/get_context.py --mode phase --step 2.1 --platform codex`
|
||||||
|
- `python3 .trellis/scripts/task.py validate .trellis/tasks/09-09-trellis-workflow-alignment`
|
||||||
|
- `node scripts/qa/check-trellis-governance.mjs`
|
||||||
|
- `node scripts/qa/check-process-contract.mjs --baseline --json`
|
||||||
|
- `node scripts/qa/audit-docs.mjs --check-registry`
|
||||||
|
- `git diff --check`
|
||||||
|
|
||||||
|
本轮不运行产品测试或部署;无业务代码更改。会话切换 fixture 使用临时目录和显式测试 context id,不触碰真实付款/恢复任务。
|
||||||
|
|
||||||
|
## 2026-09-09 执行与验证结果
|
||||||
|
|
||||||
|
执行根目录:主工作树,产品基线 b918530;本轮主工作树治理修复与 ops-preparation 既有未提交记录物理分离。未复制、修改或提交其恢复/错误解释文档。
|
||||||
|
|
||||||
|
- 官方 start/current --source 回读为本 task,session 来源;phase 2.1 返回主会话实施指引。没有写旧全局指针,没有改会话运行时实现。
|
||||||
|
- 临时目录调用官方 common.active_task:同会话 first→second 切换、两会话隔离、finish 清除当前指针但不修改 task 状态、剩余唯一会话 fallback 均通过。fixture 自动清理,没有改真实业务任务。
|
||||||
|
- 首轮 fixture 将 finish 后默认 current 应为 none 当作前提而失败;阅读官方实现后确认存在 single-session fallback,修正测试预期并补充核对来源的规约,未为让测试通过修改官方代码。
|
||||||
|
- 以当前会话环境手动运行既有 inject-workflow-state.py,断言输出含本 task、inline、trellis-before-dev,不再含旧付款任务标题。此为渲染验证,非新一轮平台实际投递验收。
|
||||||
|
- 首轮 governance 报本 task 缺 Scope/Out of Scope/Test Plan 与 metadata scope;已补齐合同并使用官方 set-scope,再跑 PASS。task validate、process contract、diff 检查通过。
|
||||||
|
- docs registry:errors=0、warnings=1,提示 22 个未注册文档。本轮没有新增 docs 文件,未扩范围批量登记或清理该警告。
|
||||||
|
- inline 主会话完成只读差异检查,无独立 reviewer;真实下一轮平台注入待观察。没有新增自动强制拦截,规则与官方解析是两层证据。
|
||||||
|
|
||||||
|
| 实施 | 发布 | 验收 | 等谁/什么 |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| 本地治理修复完成,未提交 | 不适用,不部署 | 本地运行时/渲染与治理检查通过 | 下一轮观察真实注入;独立复核未做;提交/推送/归档另批 |
|
||||||
|
|
||||||
|
官方 start 提示当前 main 与 base_branch 相同,未来 archive 的分支/PR 门禁尚未处理。本轮无新建分支或归档授权,不为消警告伪造 branch/PR/完成状态;本 task 保持 in_progress,处于本地验证完成、待交审阶段。下一项 seed 治理未激活或实施。
|
||||||
|
|
||||||
|
### 后续交接更新
|
||||||
|
|
||||||
|
用户采纳后续队列建议后,本会话实际收到的平台 workflow-state 已显示 trellis-workflow-alignment,补齐了前轮仅手动渲染、下一轮投递待观察这一项。主会话复核既有 diff 与授权边界,未发现需扩大本次修复的项;独立 reviewer 仍未执行。文件保留待提交,用户“采纳建议”不扩展成提交/推送授权。
|
||||||
|
|
||||||
|
通过官方 create 转入 09-09-existing-deploy-seed-separation 的 planning 阶段,仅创建规划合同和只读核对源码;未开始 seed 实现。前段“下一项未激活”为当时状态。后续 seed 产品改动必须独立执行工作树,不叠加到本轮待交审的治理文件。
|
||||||
|
|
||||||
|
|
||||||
|
### 经验精简:优先复用 task(用户已批准)
|
||||||
|
|
||||||
|
本轮用户明确要求更新、精简不合适经验,复用本 task 承载,不再为规则修正规划新目录。已修正 workflow 的“复杂任务先请求新建”、start 的“无当前任务就新建”以及 brainstorm 的“必须先取得新建授权”三个入口,统一为先检查当前和直接相关既有任务。完整归属规则集中在 project-governance 的 Task Reuse,其余入口引用,不为每次小修复制整套文档。
|
||||||
|
|
||||||
|
任务归属、工作树隔离、提交拆分分别决定;小修并非一律归当前任务,跨领域有现成归属则回对应 task。新增风险或实质范围仍需批准,纯咨询/微小编辑不强制 task;不批量合并、归档或重开历史任务。
|
||||||
|
|
||||||
|
本次实例:迁移状态 SIGPIPE 误判由 09-06-release-gate-integrity 的新增修复阶段承接。seed task 保留已复现证据和依赖链接,撤回“必须独立新建 task”的建议;主工作树与 seed 副本的本 task 记录同步,不迁移产品差异。门禁旧冻结交审材料及旧验收不改,新增阶段仍未实施。
|
||||||
|
|
||||||
|
本轮只读主会话检查及文档治理验证;没有独立 reviewer、提交、推送、部署或新任务目录。当前继续激活工作流修复 task,不把经验更新冒充预检产品修复。
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
# 修复 Trellis 任务切换与执行闭环
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
依据已安装官方指南修复任务激活与实际执行脱节,保持 inline 和授权边界,不改运行时或业务代码
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- 以已安装 Trellis 0.6.16 随附的 trellis-meta 官方指南及实际 CLI 为依据,核对 session active task、上下文和工作树边界。
|
||||||
|
- 修复本项目入口与收口规则中未明确检查“实际执行任务与激活任务一致”的缺口;使用官方 task.py,不新造任务指针或运行器。
|
||||||
|
- 保留 inline、session_auto_commit=false 和分别授权的提交/推送/生产操作边界。
|
||||||
|
- 本轮仅主工作树的治理文档与本 task;不搬运 ops-preparation 的恢复/错误解释改动,不改产品、官方运行时、全局安装或用户 hooks 配置。
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
主工作树 Trellis workflow、六个相关入口 skill、project-governance spec、既有 Agent 交付实践及本 task 合同;仅同步预检 finding 在已有 seed/门禁 task 间的归属,不改产品或旧门禁验收结果。
|
||||||
|
|
||||||
|
## Out of Scope
|
||||||
|
|
||||||
|
升级、运行时或 hooks 改造、产品代码、生产、提交推送归档、其他工作树的改动与其他任务状态。
|
||||||
|
|
||||||
|
## Test Plan
|
||||||
|
|
||||||
|
按 implement.md 执行官方 current/phase、临时会话 fixture、现有 hook 手动渲染与本 task 的文档治理检查。真实下一轮注入和独立复核分别标注,不以本地检查代替。
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
|
||||||
|
- [x] 本会话 current 与本任务一致;phase 输出为当前任务的 inline 实施流程。
|
||||||
|
- [x] start/continue/before-dev/check/finish 入口同步任务与工作树核对合同,不要求每轮重复读未变化资料。
|
||||||
|
- [x] 在临时隔离 fixture 中验证官方任务切换及会话隔离,不改其他真实任务状态。
|
||||||
|
- [x] task validate、Trellis governance、process contract、docs registry 与 diff 检查通过,或如实记录失败。
|
||||||
|
- [x] 明确区分运行时上下文验证、真实下一轮注入、独立复核及未提交状态。
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- 用户请求“按照trellis官方指南,检查并修复工作流”授权本范围;不包含升级或部署。方案先公布,按同范围实施。
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"id": "trellis-workflow-alignment",
|
||||||
|
"name": "trellis-workflow-alignment",
|
||||||
|
"title": "修复 Trellis 任务切换与执行闭环",
|
||||||
|
"description": "依据已安装官方指南修复任务激活与实际执行脱节,保持 inline 和授权边界,不改运行时或业务代码",
|
||||||
|
"status": "in_progress",
|
||||||
|
"dev_type": null,
|
||||||
|
"scope": "trellis-workflow",
|
||||||
|
"package": null,
|
||||||
|
"priority": "P2",
|
||||||
|
"creator": "shunli",
|
||||||
|
"assignee": "shunli",
|
||||||
|
"createdAt": "2026-09-09",
|
||||||
|
"completedAt": null,
|
||||||
|
"branch": "main",
|
||||||
|
"base_branch": "main",
|
||||||
|
"worktree_path": null,
|
||||||
|
"commit": null,
|
||||||
|
"pr_url": null,
|
||||||
|
"subtasks": [],
|
||||||
|
"children": [],
|
||||||
|
"parent": null,
|
||||||
|
"relatedFiles": [],
|
||||||
|
"notes": "",
|
||||||
|
"meta": {}
|
||||||
|
}
|
||||||
+5
-5
@@ -180,8 +180,8 @@ Phase 3: Finish → verify, update spec, commit, and wrap up
|
|||||||
|
|
||||||
### Request Triage
|
### Request Triage
|
||||||
|
|
||||||
- Pure consultation and small, isolated edits need no task unless requested. Non-trivial work needs a task and an approved plan; ask for task creation only when not already authorized.
|
- Pure consultation and small, isolated edits need no new task unless requested. Non-trivial work needs a task contract and approved plan, not necessarily a new directory.
|
||||||
- Complex task: ask whether you may create a Trellis task and enter planning. If the user says no, do not do broad inline implementation; explain, clarify scope, or suggest a smaller split.
|
- Check the current task and directly related existing tasks first. Put acceptance-related fixes in the current task; put another domain's fixes in its existing task with a scoped follow-up stage. Create a task only for independently managed work without a suitable existing owner, with creation consent when not already authorized. Do not expand an existing task silently or reopen archived tasks automatically.
|
||||||
- User approval to create a task is not approval to start implementation. Planning still happens first.
|
- User approval to create a task is not approval to start implementation. Planning still happens first.
|
||||||
|
|
||||||
### Planning Artifacts
|
### Planning Artifacts
|
||||||
@@ -194,7 +194,7 @@ Phase 3: Finish → verify, update spec, commit, and wrap up
|
|||||||
|
|
||||||
### Parent / Child Task Trees
|
### Parent / Child Task Trees
|
||||||
|
|
||||||
Use a parent task when one user request contains several independently verifiable deliverables. The parent task owns the source requirement set, the task map, cross-child acceptance criteria, and final integration review; it normally should not be the implementation target unless it also has direct work.
|
Use a parent task when genuinely new, independently managed deliverables need one; reuse suitable existing task contracts first. A small fix, separate worktree or separate commit alone does not require a child task. The parent owns cross-deliverable requirements and acceptance, not every incidental fix.
|
||||||
|
|
||||||
Use child tasks for deliverables that can be planned, implemented, checked, and archived independently. Parent/child structure is not a dependency system: if one child must wait for another, write that ordering in the child `prd.md` / `implement.md` and keep each child's acceptance criteria testable.
|
Use child tasks for deliverables that can be planned, implemented, checked, and archived independently. Parent/child structure is not a dependency system: if one child must wait for another, write that ordering in the child `prd.md` / `implement.md` and keep each child's acceptance criteria testable.
|
||||||
|
|
||||||
@@ -203,9 +203,9 @@ Create new children with `task.py create "<title>" --slug <name> --parent <paren
|
|||||||
<!-- Per-turn breadcrumb: shown when there is no active task (before Phase 1) -->
|
<!-- Per-turn breadcrumb: shown when there is no active task (before Phase 1) -->
|
||||||
|
|
||||||
[workflow-state:no_task]
|
[workflow-state:no_task]
|
||||||
No active task. First classify the current turn and ask for task-creation consent before creating any Trellis task.
|
No active task. First classify the turn; no active pointer does not mean no suitable task exists.
|
||||||
Pure consultation or a small isolated edit: respond or execute within scope without asking to create a task.
|
Pure consultation or a small isolated edit: respond or execute within scope without asking to create a task.
|
||||||
Complex task: ask the user if you can create a Trellis task and enter the planning phase. If the user says no, explain, clarify scope, or suggest a smaller split.
|
For tracked work, check directly related existing tasks and reuse a suitable contract. Activate already approved work with the official task command; new scope still needs review. Only request new-task creation when no suitable owner exists and creation is not already authorized. Do not create tasks merely for separate commits or worktrees.
|
||||||
[/workflow-state:no_task]
|
[/workflow-state:no_task]
|
||||||
|
|
||||||
<!-- Per-turn breadcrumb: shown when the active task record cannot be read. -->
|
<!-- Per-turn breadcrumb: shown when the active task record cannot be read. -->
|
||||||
|
|||||||
在新工单中引用
屏蔽一个用户