Skip to content
This repository was archived by the owner on Aug 24, 2026. It is now read-only.

feat: 场景引擎与测试底层方法统一(ADR-0014,ADR-0013 系列 PR-C) - #13

Closed
randypanding wants to merge 5 commits into
owner-control-observabilityfrom
scenario-engine
Closed

feat: 场景引擎与测试底层方法统一(ADR-0014,ADR-0013 系列 PR-C)#13
randypanding wants to merge 5 commits into
owner-control-observabilityfrom
scenario-engine

Conversation

@randypanding

Copy link
Copy Markdown
Contributor

基于 #12(PR-B)——合并顺序:#11#12 → 本 PR

解决什么

"流程本身也需要是声明式的;做出来要考虑如何模拟、未来流程怎么测试;测试的底层方法要代码化要统一。"(ADR-0014)

核心命题

流程、角色、治理声明完备后,组织的一切行为都是状态机转移——可枚举即可测试。统一底层方法:

一切测试 = 事件进 → 事件出 → 断言不变式(三层):

  • L1 断言原语(A1-A7,不变):全场景共用——这是"统一"的本体
  • L2 场景剧本(scenarios.yaml):声明化,可 diff/可 PR review/新增场景零代码
  • L3 门禁:PR 跑回归场景;CT 声明层先决跑 control 场景;运行时攻击面 adversary 执行

变更

1. scenarios.yaml:17 场景注册表

  • S1-S12 存量:hook 保留(复杂跨结构推导),元数据+ct_refs 入表
  • S13-S17 新场景纯声明式(零 Python):S13 trivial 直通 / S14 maintain loop(issue 五态无第四态)/ S15 maintenance wave / S16 owner pause-abort / S17 未批意图拒绝(control 类)
  • 断言格式:{path, op, value},op ∈ {exists, eq, contains, not_contains, contains_all}

2. simulate-wave.py 引擎化

声明式断言求值器(路径解析+op 求值);run() 注册表驱动;hook 双向一致性检查(声明 hook 不存在/实现未登记=漂移=FAIL)。

3. CT 双层链接(29 条全部完成)

"假防线"从无法发现变为机器可判(ADR-0012 发现 adr-required 悬空是人工摸底,现在制度化了):

  • scenario: 声明层先决(模拟器绿=CT 前提成立;null 须显式)
  • runtime: adversary-executed×10 / validate-executed×3 / manual_only×16(每条带 runtime_note 理由——理由清单即待自动化的攻击面清单

4. validate 双向校验

CT 引用场景必须存在;scenario.ct_refs 引用 CT 必须存在;manual_only 无理由=CI 拒绝。

验证

validate OK + simulate 17 场景全通(30 声明式断言+12 hook);负向测试 3 连(悬空场景引用/声明式断言失败/manual_only 无理由)均 FAIL 拦截。

诚实边界(写进 scenarios.yaml 头部)

模拟测"声明的世界";实现的世界归 gate/verifier;防线真实有效归 escape_review/CT——三层各管一段,不互相冒充。S1-S12 hook 迁移纯声明式=后续增量(不假装一次完成)。

@coderabbitai

coderabbitai Bot commented Aug 18, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 00bf8621-7191-4743-8eea-40947f62656a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

统一声明式场景引擎与控制测试门禁

✨ Enhancement 🧪 Tests 📝 Documentation ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

AI Description

• 新增 17 项场景注册表,统一流程剧本与不变式断言。
• 场景模拟器改为注册表驱动,并检测声明与 Hook 漂移。
• 链接 29 项控制测试,校验场景先决与运行时执行方式。
Diagram

graph TD
  SC["场景注册表"] -->|驱动| ENG["场景引擎"] -->|结果| GATE["CI 门禁"]
  DECL["治理声明"] -->|被断言| ENG
  HOOK["遗留 Hooks"] -->|补充语义| ENG
  SC -->|引用校验| VAL["链接校验器"] -->|结果| GATE
  CT["控制测试"] -->|引用校验| VAL
  CT -->|执行分类| ADV["运行时验证"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. 采用 JSONPath/JMESPath 求值
  • ➕ 使用成熟路径语法,减少自定义解析边界
  • ➕ 更容易扩展过滤、数组和类型化比较
  • ➖ 增加运行时依赖和学习成本
  • ➖ 当前有限断言集合不需要完整查询语言
2. 使用 pytest 参数化场景
  • ➕ 可直接复用测试发现、隔离和报告能力
  • ➕ 复杂断言具有更清晰的 Python 类型语义
  • ➖ 场景仍依赖代码,削弱 YAML 的可审查性
  • ➖ 非开发角色新增场景的门槛更高

Recommendation: 当前 YAML 注册表加轻量求值器最符合“新增场景零代码”和治理声明可审查的目标,同时保留 Hook 处理复杂语义。建议维持该方案;只有当路径过滤、类型比较或错误定位需求显著增长时,再迁移到成熟查询库。

Files changed (5) +431 / -10

Enhancement (2) +129 / -10
simulate-wave.py将流程模拟器改为场景注册表驱动 +106/-10

将流程模拟器改为场景注册表驱动

• 新增声明路径解析和五类断言操作,并按 scenarios.yaml 执行全部场景。通过装饰器登记存量 Hook,双向检测 Hook 与场景声明漂移,并按场景类别汇总结果。

scripts/simulate-wave.py

validate.py校验场景与控制测试链接完整性 +23/-0

校验场景与控制测试链接完整性

• 检查控制测试引用的场景、场景引用的 CT 以及 runtime 枚举是否有效。要求 manual_only 测试提供不可自动化的原因说明。

scripts/validate.py

Tests (1) +156 / -0
scenarios.yaml建立 17 项声明式场景注册表 +156/-0

建立 17 项声明式场景注册表

• 登记 S1-S12 存量 Hook 场景及其 CT 引用,并新增 S13-S17 五个纯声明式场景。场景通过统一路径和操作符描述 30 项断言,覆盖回归与控制测试先决。

standards/scenarios.yaml

Documentation (1) +75 / -0
ADR-0014-scenario-engine.md记录场景引擎与统一测试方法决策 +75/-0

记录场景引擎与统一测试方法决策

• 定义“事件进、事件出、断言不变式”的三层测试模型,说明声明式场景、CT 双层链接及注册表驱动执行。明确模拟、门禁和运行时控制测试各自的责任边界。

decisions/ADR-0014-scenario-engine.md

Other (1) +71 / -0
control-tests.yaml补全 29 项控制测试的执行元数据 +71/-0

补全 29 项控制测试的执行元数据

• 为每项控制测试声明场景先决和运行时执行方式。对 16 项 manual_only 测试补充原因,显式记录尚待自动化的运行时攻击面。

standards/control-tests.yaml

@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (4) 📘 Rule violations (1) 📜 Skill insights (0)

Grey Divider


Action required

1. Structured assertions match substrings 🐞 Bug ≡ Correctness
Description
contains, not_contains, and contains_all stringify lists and mappings before searching, so
they test substrings rather than exact members. For example, S16's required paused state would
still pass if the lifecycle contained only unpaused, allowing a broken declaration to remain
green.
Code

scripts/simulate-wave.py[R175-183]

+    s = val if isinstance(val, str) else str(val)
+    if op == "eq":
+        return None if s == str(want) else f"{a['path']}={s!r} != {want!r}"
+    if op == "contains":
+        return None if str(want) in s else f"{a['path']} 不含 {want!r}(实={s[:80]!r})"
+    if op == "not_contains":
+        return None if str(want) not in s else f"{a['path']} 不应含 {want!r}"
+    if op == "contains_all":
+        missing = [w for w in want if str(w) not in s]
Relevance

●●● Strong

Exact-membership bug is deterministic and directly undermines the PR's declared assertion semantics.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The evaluator converts every non-string value with str() and then uses substring membership. S16
applies contains_all to the card lifecycle state list, so similarly named but invalid states can
satisfy the assertion without exact membership.

scripts/simulate-wave.py[167-185]
standards/scenarios.yaml[132-143]
standards/team-collaboration.yaml[305-312]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The declarative assertion evaluator converts structured YAML values to strings before applying containment operations. This allows partial matches in unrelated keys or values and can make scenario assertions pass when required list members are absent.

## Issue Context
String values may continue using substring semantics, but lists should use exact element membership and mappings should use explicit key/value semantics. `contains_all` should require every expected item to be an exact member of a collection.

## Fix Focus Areas
- scripts/simulate-wave.py[167-185]
- standards/scenarios.yaml[132-143]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Malformed CT bypasses validation 🐞 Bug ≡ Correctness
Description
The CT loop silently skips every non-mapping test value, while existing coverage checks only require
the CT ID to be present. Replacing a referenced CT definition with a scalar therefore bypasses all
new scenario, runtime, and runtime_note requirements without failing validation.
Code

scripts/validate.py[R450-452]

+for cid, ct in CT_TESTS.items():
+    if not isinstance(ct, dict):
+        continue
Relevance

●●● Strong

PR #10 accepted the same fail-open pattern: malformed registry entries must fail, not be skipped.

PR-#10

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Profile coverage treats membership in CT_REG as sufficient, whereas the new validation explicitly
continues past non-dictionary entries. Thus the ID remains registered but none of its required
ADR-0014 fields are checked; past PR #10 documents the same fail-open registry-shape pattern in this
validator.

scripts/validate.py[152-178]
scripts/validate.py[443-460]
PR-#10

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Non-mapping control-test entries are silently skipped, allowing an existing CT ID to retain coverage membership while bypassing the new runtime and scenario metadata checks.

## Issue Context
Every CT entry must first be validated as a mapping. Invalid entries should call `fail()` and then be skipped only to avoid secondary exceptions; they must never be accepted silently. Add regression coverage for scalar, list, and null CT definitions.

## Fix Focus Areas
- scripts/validate.py[152-178]
- scripts/validate.py[443-460]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

3. S11 links wrong control 🐞 Bug ≡ Correctness
Description
S11 lists CT-ADV-003, whose own scenario is null and whose claim concerns CT coverage, while the
S11 hook explicitly verifies the CT-RES-002 source requirement. This makes the scenario registry
omit its actual linked control test and advertise an unrelated one.
Code

standards/scenarios.yaml[R85-86]

+    hook: scenario_trust_chain
+    ct_refs: [CT-ADV-003]
Relevance

●●● Strong

The referenced control conflicts directly with the hook's stated behavior and the registry's actual
S11 mapping.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The S11 hook checks that findings.json requires at least one source and labels failure as
CT-RES-002. Control-tests assigns CT-RES-002 to S11, whereas CT-ADV-003 declares no scenario and
checks one-to-one CT coverage instead.

standards/scenarios.yaml[81-86]
scripts/simulate-wave.py[593-600]
standards/control-tests.yaml[170-194]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
S11's `ct_refs` points to CT-ADV-003 even though its hook explicitly enforces CT-RES-002 and CT-RES-002 declares S11 as its scenario prerequisite.

## Issue Context
Replace the unrelated reference and strengthen validation so a CT naming a scenario must be represented consistently in that scenario's references, unless asymmetric links are explicitly modeled and documented.

## Fix Focus Areas
- standards/scenarios.yaml[81-86]
- standards/control-tests.yaml[170-194]
- scripts/simulate-wave.py[570-603]
- scripts/validate.py[443-464]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


4. Malformed scenarios crash validation 🐞 Bug ☼ Reliability
Description
The new reverse-link loop calls spec.get() without verifying that each scenario is a mapping, so
valid YAML such as S18: null or S18: [] terminates validation with an uncaught AttributeError.
The scenario engine has the same unchecked assumption and also crashes instead of reporting a
registry failure.
Code

scripts/validate.py[R461-464]

+for sid, spec in SCEN.items():
+    for ref in (spec.get("ct_refs") or []):
+        if ref not in CT_TESTS:
+            fail(f"scenario {sid} ct_refs 引用不存在的 {ref}(悬空 CT 引用)")
Relevance

●●● Strong

PR #10 accepted shape-checking YAML containers before mapping access to prevent crashes.

PR-#10

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The validator directly invokes spec.get('ct_refs'), while the simulator invokes several
spec.get() calls and indexes assertion path values without shape checks. Past PR #10 accepted
the same class of unchecked YAML container assumption as a validator defect.

scripts/validate.py[447-464]
scripts/simulate-wave.py[167-185]
scripts/simulate-wave.py[631-656]
PR-#10

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Structurally malformed scenario entries cause uncaught exceptions in both validation and simulation instead of producing controlled diagnostics.

## Issue Context
Validate that the scenarios root is a mapping, each scenario is a mapping, `asserts` and `ct_refs` are lists, and each assertion has the required mapping fields before dereferencing them. Add malformed-root and malformed-entry regression tests.

## Fix Focus Areas
- scripts/validate.py[443-464]
- scripts/simulate-wave.py[167-185]
- scripts/simulate-wave.py[631-656]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. Cross-registry links skip approval status 📘 Rule violation ≡ Correctness
Description
The new scenario and ct_refs links reference registry entries that have no status, while
validation only confirms that targets exist. Consequently, references to unapproved or deprecated
entries cannot be rejected.
Code

standards/scenarios.yaml[30]

+    ct_refs: [CT-BLD-002, CT-PLN-001, CT-PLN-002, CT-TA-001, CT-RLB-001]
Relevance

●● Moderate

Approval-status propagation is a policy concern, but history lacks a close cross-registry precedent.

PR-#5

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Rule 2771006 requires referenced registry entries to have approved status. S1-happy-path adds
references to control tests, but the complete CT-BLD-002 entry has no status; the reverse
scenario link likewise targets an S1-happy-path entry without status, and the new validator
checks only target existence.

Rule 2771006: Registry entries must only reference entries with approved status
standards/scenarios.yaml[25-30]
standards/control-tests.yaml[18-25]
scripts/validate.py[450-464]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The scenario and control-test registries now reference each other, but referenced entries do not declare `status: approved` and the validator does not enforce approval status.

## Issue Context
PR Compliance ID 2771006 requires every referenced registry entry to exist and have an exactly approved status. Add a required status field to both registry schemas and fail validation when a referenced scenario or control test is not approved.

## Fix Focus Areas
- standards/control-tests.yaml[9-255]
- standards/scenarios.yaml[22-156]
- scripts/validate.py[450-464]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context sources
✅ Compliance rules (platform): 7 rules
Review mode: ⚖️ Balanced: Downgraded extended -> standard: change is below the extended eligibility bar (hunks 17/18, lines 441/200; both must reach the floor). Router rationale: 该 PR 同时改动声明式断言引擎、场景注册与 hook 调度、CT 双向校验及多份 YAML 数据,存在多个跨文件且易遗漏的独立逻辑缺陷,冗余复审有明显价值。

Grey Divider

Tip of the day
💡 Did you know, you can keep summaries lean with Finding overflow, which tucks the rest behind 'View more'

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread standards/scenarios.yaml
narrative: 意图→组队→planner 产卡→test_author 冻结测试树→card_gate→build→verify
(verifier 判卷+review)→integrator 合并→release_bot behind flag→handoff→销毁
hook: scenario_happy_path
ct_refs: [CT-BLD-002, CT-PLN-001, CT-PLN-002, CT-TA-001, CT-RLB-001]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

1. Cross-registry links skip approval status 📘 Rule violation ≡ Correctness

The new scenario and ct_refs links reference registry entries that have no status, while
validation only confirms that targets exist. Consequently, references to unapproved or deprecated
entries cannot be rejected.
Agent Prompt
## Issue description
The scenario and control-test registries now reference each other, but referenced entries do not declare `status: approved` and the validator does not enforce approval status.

## Issue Context
PR Compliance ID 2771006 requires every referenced registry entry to exist and have an exactly approved status. Add a required status field to both registry schemas and fail validation when a referenced scenario or control test is not approved.

## Fix Focus Areas
- standards/control-tests.yaml[9-255]
- standards/scenarios.yaml[22-156]
- scripts/validate.py[450-464]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread scripts/simulate-wave.py
Comment on lines +175 to +183
s = val if isinstance(val, str) else str(val)
if op == "eq":
return None if s == str(want) else f"{a['path']}={s!r} != {want!r}"
if op == "contains":
return None if str(want) in s else f"{a['path']} 不含 {want!r}(实={s[:80]!r})"
if op == "not_contains":
return None if str(want) not in s else f"{a['path']} 不应含 {want!r}"
if op == "contains_all":
missing = [w for w in want if str(w) not in s]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

2. Structured assertions match substrings 🐞 Bug ≡ Correctness

contains, not_contains, and contains_all stringify lists and mappings before searching, so
they test substrings rather than exact members. For example, S16's required paused state would
still pass if the lifecycle contained only unpaused, allowing a broken declaration to remain
green.
Agent Prompt
## Issue description
The declarative assertion evaluator converts structured YAML values to strings before applying containment operations. This allows partial matches in unrelated keys or values and can make scenario assertions pass when required list members are absent.

## Issue Context
String values may continue using substring semantics, but lists should use exact element membership and mappings should use explicit key/value semantics. `contains_all` should require every expected item to be an exact member of a collection.

## Fix Focus Areas
- scripts/simulate-wave.py[167-185]
- standards/scenarios.yaml[132-143]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread scripts/validate.py
Comment on lines +450 to +452
for cid, ct in CT_TESTS.items():
if not isinstance(ct, dict):
continue

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

3. Malformed ct bypasses validation 🐞 Bug ≡ Correctness

The CT loop silently skips every non-mapping test value, while existing coverage checks only require
the CT ID to be present. Replacing a referenced CT definition with a scalar therefore bypasses all
new scenario, runtime, and runtime_note requirements without failing validation.
Agent Prompt
## Issue description
Non-mapping control-test entries are silently skipped, allowing an existing CT ID to retain coverage membership while bypassing the new runtime and scenario metadata checks.

## Issue Context
Every CT entry must first be validated as a mapping. Invalid entries should call `fail()` and then be skipped only to avoid secondary exceptions; they must never be accepted silently. Add regression coverage for scalar, list, and null CT definitions.

## Fix Focus Areas
- scripts/validate.py[152-178]
- scripts/validate.py[443-460]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread standards/scenarios.yaml
Comment on lines +85 to +86
hook: scenario_trust_chain
ct_refs: [CT-ADV-003]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

4. S11 links wrong control 🐞 Bug ≡ Correctness

S11 lists CT-ADV-003, whose own scenario is null and whose claim concerns CT coverage, while the
S11 hook explicitly verifies the CT-RES-002 source requirement. This makes the scenario registry
omit its actual linked control test and advertise an unrelated one.
Agent Prompt
## Issue description
S11's `ct_refs` points to CT-ADV-003 even though its hook explicitly enforces CT-RES-002 and CT-RES-002 declares S11 as its scenario prerequisite.

## Issue Context
Replace the unrelated reference and strengthen validation so a CT naming a scenario must be represented consistently in that scenario's references, unless asymmetric links are explicitly modeled and documented.

## Fix Focus Areas
- standards/scenarios.yaml[81-86]
- standards/control-tests.yaml[170-194]
- scripts/simulate-wave.py[570-603]
- scripts/validate.py[443-464]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread scripts/validate.py
Comment on lines +461 to +464
for sid, spec in SCEN.items():
for ref in (spec.get("ct_refs") or []):
if ref not in CT_TESTS:
fail(f"scenario {sid} ct_refs 引用不存在的 {ref}(悬空 CT 引用)")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

5. Malformed scenarios crash validation 🐞 Bug ☼ Reliability

The new reverse-link loop calls spec.get() without verifying that each scenario is a mapping, so
valid YAML such as S18: null or S18: [] terminates validation with an uncaught AttributeError.
The scenario engine has the same unchecked assumption and also crashes instead of reporting a
registry failure.
Agent Prompt
## Issue description
Structurally malformed scenario entries cause uncaught exceptions in both validation and simulation instead of producing controlled diagnostics.

## Issue Context
Validate that the scenarios root is a mapping, each scenario is a mapping, `asserts` and `ct_refs` are lists, and each assertion has the required mapping fields before dereferencing them. Add malformed-root and malformed-entry regression tests.

## Fix Focus Areas
- scripts/validate.py[443-464]
- scripts/simulate-wave.py[167-185]
- scripts/simulate-wave.py[631-656]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

回答"我下达意图到最后完成,流程是什么":
- standards/intent-routing.yaml:八分类路由表(deliver/fix/respond/investigate/
  maintain/govern/spawn/ask),每类声明 {载体, 验收来源, owner 同步成本, flow_ref};
  三立场:不设多套流程(R1)/owner 从不启动任何东西(R2,分类=interface-gateway
  机制判定,歧义按更重一侧路由+问一次)/注意力只花在新对错(R3)
- 验收三分法落地 flows.yaml#intent_ratification.shortcuts:new_ratable(新批)/
  self_evident(自明——fix 意图原文即验收)/pre_approved(预批准——复绿即验收,
  不可迁移到新验收面)/predetermined/evidence_based
- change-classes +trivial(fix 载体:自明验收+verifier 判卷不豁免+promote_if 四条
  路径规则防"小修"定义膨胀)+spike(investigate 载体:无合并面产 ADR/finding,
  evidence_based——此前无载体类,真实缺口)
- flows.yaml#maintain_loop:issue 五态生命周期(open→triage→consumed→closed/deferred),
  不变式"issue 不可能躺在列表里"(消费/驳回/带条件延期三选一);maintenance_wave
  自救通道(security 级 OR aging>30d 触发——周扫问题无人手动启动 agent 的结构答案)
- team-collaboration backlog 接口 +maintenance_trigger(引用 flows 单一真源)
- validate.py fail-closed:路由引用的 change_class/团队原型必须存在;trivial/spike
  不可成孤类(负向测试:删 fix 路由→FAIL exit=1)

验证:validate OK + simulate 12 场景全通。系列:PR-B(owner 控制+可观测)/
PR-C(场景声明化+测试引擎统一)。
可观测与控制一体两面:同一事件流的读端(TUI/agent 查询)与写端(控制动词),
不新建设施,不出现"看得到控不了、控了看不到"。

- standards/observability.yaml:原则(read_only/attention_first/provenance)+
  TUI 六视图(attention 默认页=等决策队列+SLA 倒计时/now/wave/budget/backlog/trace)+
  log 三级受众投影(owner/机制/审计——同一事件流三个读端投影,非三套日志)+
  ask 检索契约(researcher as_tool,回答必附引用,与 TUI 同源同投影)
- flows.yaml#owner_control:pause=停表停预算(wall_clock 不计暂停,usd 已花照记);
  abort=不可逆+reason 必填,reason_routing 三路善后(need_gone 作废/spec_wrong 退
  backlog 接 escape 回路/superseded 关联新卡);不变式:控制动词=事件不是凭据
  (TUI 无数据层写凭据);注意力账本零新增(账本管系统等 owner,owner 主动出手不入账)
- team-collaboration:卡生命周期 +paused/aborted 状态(owner_control_ref 单一真源
  引用);event_producers +card.paused/resumed/aborted(owner 经平台通道);
  services +tui 机制(视图物化+控制入站——fail-closed 注册);interface_gateway
  duty 扩展 ask 路由与控制动词入站

验证:validate OK + simulate 12 场景全通 + 语义链核对脚本通过(六视图/三事件有主/
tui 注册/paused+aborted 状态)。基于 PR-A 分支(#11 合并后自然 rebase)。
统一方法论:一切测试 = 事件进 → 事件出 → 断言不变式(L1 原语 A1-A7 不变 /
L2 场景剧本 YAML 声明化 / L3 门禁 PR 回归+CT 先决)。

- standards/scenarios.yaml:场景注册表(17 场景)。S1-S12 存量(hook 保留,
  元数据+ct_refs 入表);S13-S17 新场景纯声明式(零 Python):S13 trivial 直通 /
  S14 maintain loop(issue 五态无第四态)/ S15 maintenance wave 触发 / S16 owner
  pause-abort / S17 未批意图拒绝(control 类=CT-PLN-003 声明层先决)
- simulate-wave.py:引擎化——声明式断言求值器(path+op 统一求值,支持数字键);
  run() 注册表驱动(hook 双向一致性=漂移检测);输出 class 统计
- control-tests.yaml:29 条 CT 全部链接 scenario(声明层先决)+ runtime
  (adversary-executed×10 / validate-executed×3 / manual_only×16 各带 runtime_note
  理由——理由清单即待自动化攻击面清单)
- validate.py:CT↔scenario 双向校验(悬空引用/非法 runtime/manual_only 无理由=FAIL)

验证:validate OK + simulate 17 场景全通(30 声明式断言+12 hook);负向测试 3 连
(CT 悬空场景/声明式断言失败/manual_only 无理由均 FAIL 拦截)。
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant