Skip to content

fix: 声明级流程走查修复(4 子代理审计结论落地) - #17

Merged
randypanding merged 1 commit into
mainfrom
fix-flow-audit
Aug 19, 2026
Merged

fix: 声明级流程走查修复(4 子代理审计结论落地)#17
randypanding merged 1 commit into
mainfrom
fix-flow-audit

Conversation

@randypanding

Copy link
Copy Markdown
Contributor

4 个子代理并行走查全部流程声明,发现并修复 6 处缺陷:

  1. resume 升顶层动词(flows owner_control):原是 pause 子属性,与 observability verbs [pause,resume,abort] 及 card.resumed 事件生产者三方不对齐——补 event 声明与 target_states
  2. maintenance_wave 组队触发承接:delivery_squad 原型与 dev-wave 实例 lifecycle.trigger 只有 intent.received,curator 提请的维护波次无组队入口——扩为 intent.received OR maintenance_wave.trigger
  3. backlog 条目契约:maintenance_wave.trigger 引用的 severity/aging 字段无 schema 真源——新增 registry/schemas/backlog-entry.json + interfaces.backlog.entry_schema 引用(含 rejected 必填 reason / deferred 必填机器可判定条件的条件约束,呼应无第四态)
  4. 账本 security 升级归属:maintain security 级升 owner_ratify 无账本条目(违反账本为证)——并入 dep_and_schema_owner_ratify(语义同族,不新增条目守恒)
  5. ADR-0015 文档漂移:runtime 拆分 10/3/16 → 实际 13/3/13 回填
  6. 防复发:新增 5 条声明式断言锁上述对齐(30→35 条)

本地:validate OK / 17 场景全通 / pytest 20 passed

@coderabbitai

coderabbitai Bot commented Aug 19, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@randypanding, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 22 minutes

Limit details: You’ve used all 3 included reviews currently available.

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits within each organization.

For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 715aa805-c9fc-4254-83d5-ff0799e90fc4

📥 Commits

Reviewing files that changed from the base of the PR and between 3a3331b and 633c99a.

📒 Files selected for processing (7)
  • decisions/ADR-0015-scenario-engine.md
  • registry/schemas/backlog-entry.json
  • registry/teams/dev-wave.yaml
  • standards/attention-ledger.yaml
  • standards/flows.yaml
  • standards/scenarios.yaml
  • standards/team-collaboration.yaml

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

@randypanding
randypanding merged commit 7f514cc into main Aug 19, 2026
7 checks passed
@randypanding
randypanding deleted the fix-flow-audit branch August 19, 2026 02:02
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Align maintenance and owner-control workflow declarations

🐞 Bug fix 🧪 Tests ⚙️ Configuration changes 📝 Documentation 🕐 20-40 Minutes

Grey Divider

AI Description

• Aligns resume events and maintenance-wave assembly across workflow declarations.
• Adds a backlog schema and routes security approvals through the attention ledger.
• Adds five regression assertions and corrects ADR runtime classification counts.
Diagram

graph TD
  B["Backlog Contract"] --> M{"Maintenance Trigger"} --> D["Delivery Squad"]
  M -->|security| L["Attention Ledger"]
  O["Observability Verbs"] --> C["Owner Control"] --> E["Card Events"]
  S["Scenario Assertions"] -.-> B
  S -.-> C
Loading
High-Level Assessment

The PR's declarative single-source-of-truth approach is appropriate. Inline backlog fields would duplicate contracts, while a separate security ledger item would fragment equivalent owner-ratification work; a referenced schema, reused ledger category, and cross-file scenario assertions provide the clearest alignment with minimal conceptual expansion.

Files changed (7) +58 / -9

Bug fix (5) +50 / -6
backlog-entry.jsonDefine the canonical backlog entry contract +33/-0

Define the canonical backlog entry contract

• Adds a JSON Schema for backlog identity, source, severity, aging, evidence, and disposition. Conditional constraints require rejection reasons and machine-evaluable deferral conditions for their respective dispositions.

registry/schemas/backlog-entry.json

dev-wave.yamlAllow maintenance waves to assemble dev teams +3/-1

Allow maintenance waves to assemble dev teams

• Extends the concrete dev-wave lifecycle trigger to accept either a received intent or a curator-requested maintenance wave.

registry/teams/dev-wave.yaml

attention-ledger.yamlRoute security maintenance approvals through the ledger +2/-1

Route security maintenance approvals through the ledger

• Assigns security-level maintenance escalation to the existing dependency-and-schema owner-ratification entry, preserving ledger category conservation.

standards/attention-ledger.yaml

flows.yamlPromote resume to a complete owner-control verb +4/-1

Promote resume to a complete owner-control verb

• Defines resume alongside pause and abort with paused-state eligibility, restoration semantics, and the card.resumed event declaration.

standards/flows.yaml

team-collaboration.yamlConnect maintenance backlog entries to squad lifecycle +8/-3

Connect maintenance backlog entries to squad lifecycle

• Extends the delivery-squad prototype to assemble from maintenance-wave triggers and references the new backlog-entry schema as the interface contract.

standards/team-collaboration.yaml

Tests (1) +5 / -0
scenarios.yamlAdd regression assertions for declaration alignment +5/-0

Add regression assertions for declaration alignment

• Adds five assertions covering maintenance-wave assembly, backlog schema exposure, owner-control verb completeness, and resume event production.

standards/scenarios.yaml

Documentation (1) +3 / -3
ADR-0015-scenario-engine.mdCorrect scenario runtime classification totals +3/-3

Correct scenario runtime classification totals

• Updates the 29 CT runtime split from 10/3/16 to the actual 13 adversary-executed, 3 validate-executed, and 13 manual-only scenarios.

decisions/ADR-0015-scenario-engine.md

@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (5) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Disposition conditions match absence 🐞 Bug ≡ Correctness
Description
Both conditional schemas treat a missing disposition as a match, so an otherwise valid open entry
is incorrectly required to contain both reason and defer_condition. This makes the newly
declared backlog contract reject entries before producer-gate disposition.
Code

registry/schemas/backlog-entry.json[R25-26]

+      "if": {"properties": {"disposition": {"const": "rejected"}}},
+      "then": {"required": ["reason"]}
Relevance

●●● Strong

Missing discriminator requirements cause deterministic validation failure, matching the repository’s
accepted fail-closed fixes.

PR-#5

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The top-level required list omits disposition, while both if blocks use only properties;
therefore an object without disposition satisfies both conditions. The JSON Schema documentation
explicitly warns that required is necessary in if schemas or they apply when the discriminator
is undefined.

registry/schemas/backlog-entry.json[7-30]
standards/flows.yaml[73-80]
🌐 The conditional-schema documentation states that required is necessary in if schemas to prevent them applying when the tested property is undefined.

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 `rejected` and `deferred` JSON Schema conditions also match when `disposition` is absent, causing both conditional fields to become required.

## Issue Context
Under JSON Schema semantics, `properties` validates only properties that are present; it does not require `disposition` to exist. Each `if` must explicitly require the discriminator.

## Fix Focus Areas
- registry/schemas/backlog-entry.json[23-31]

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



Remediation recommended

2. Drift reference remains optional 🐞 Bug ≡ Correctness
Description
Entries with source: drift can pass the schema without expected_state_ref, despite both the
schema description and issue lifecycle requiring that reference. Such entries lose the
expected-state anchor needed to triage and repair drift.
Code

registry/schemas/backlog-entry.json[R16-17]

+    "evidence": {"type": "string", "description": "指标/证据/期望状态引用(issue 链接或 drift 报告锚点)"},
+    "expected_state_ref": {"type": "string", "description": "期望状态引用(governance/expected-state.json 锚点,drift 类必填)"},
Relevance

●●● Strong

Recent accepted reviews favor fail-closed contract fixes for declared lifecycle invariants and
validation gaps.

PR-#5

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The property description says expected_state_ref is required for drift entries, and the flow says
scanner-created issues include an expected-state reference. Nevertheless, it is absent from the
required list and no source-specific condition exists, so a source: drift, disposition: open entry
without it validates.

registry/schemas/backlog-entry.json[7-17]
standards/flows.yaml[73-75]

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 schema describes `expected_state_ref` as mandatory for drift entries but never conditionally requires it.

## Issue Context
Add a discriminator condition for `source: drift`, including `required: [source]`, whose `then` requires `expected_state_ref`.

## Fix Focus Areas
- registry/schemas/backlog-entry.json[16-31]

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


3. Empty disposition metadata accepted 🐞 Bug ≡ Correctness
Description
The schema accepts reason: "" for rejected entries and defer_condition: "" for deferred entries
because both fields are unconstrained strings. These values satisfy required while violating the
lifecycle’s mandatory reason and machine-evaluable deferral condition.
Code

registry/schemas/backlog-entry.json[R20-21]

+    "reason": {"type": "string", "description": "disposition=rejected 时的驳回理由(必填)"},
+    "defer_condition": {"type": "string", "description": "disposition=deferred 时的机器可判定条件(必填;到期由 curator 机制扫描重排 top-k)"}
Relevance

●●● Strong

This is a deterministic schema correctness gap; recent accepted reviews strengthen machine-enforced
contracts.

PR-#5

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Both metadata fields specify only type: string, so empty strings pass their conditional required
checks. The governing flow requires an actual rejection reason and a machine-decidable condition
rather than mere field presence.

registry/schemas/backlog-entry.json[18-21]
standards/flows.yaml[76-81]
standards/team-collaboration.yaml[352-355]

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

## Issue description
Required disposition metadata can currently be empty and still satisfy the schema.

## Issue Context
At minimum, enforce non-empty values with `minLength`; define and validate a structured condition or expression grammar if `defer_condition` must be machine-evaluable.

## Fix Focus Areas
- registry/schemas/backlog-entry.json[18-21]
- registry/schemas/backlog-entry.json[23-31]

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


4. Schema assertion checks only scalar 🐞 Bug ☼ Reliability
Description
The new S15 assertion verifies only that entry_schema contains a non-null scalar, not that the
referenced file exists or parses as JSON Schema. Deleting, misspelling, or corrupting
backlog-entry.json therefore leaves the advertised anti-regression scenario and repository
validator green.
Code

standards/scenarios.yaml[133]

+      - {path: "standards/team-collaboration.yaml#interfaces.backlog.entry_schema", op: exists}
Relevance

●● Moderate

The concern matches accepted parser-gap hardening, but stronger reference validation is
architectural and similar validation expansion was recently rejected.

PR-#5
PR-#11

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
exists succeeds whenever path resolution returns any non-null scalar. validate.py checks schema
files referenced by agent/tool io_contracts, but has no equivalent lookup for
interfaces.backlog.entry_schema; the past accepted parser-gap bug demonstrates the same failure
mode of declaring a file without loading it in CI.

standards/scenarios.yaml[126-133]
scripts/simulate-wave.py[167-185]
scripts/validate.py[255-301]
PR-#5

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 regression assertion checks the reference key but never resolves or validates its target.

## Issue Context
Resolve `interfaces.backlog.entry_schema` within the repository, reject escaping or missing paths, parse the target as JSON, and validate it as a Draft 2020-12 schema. Add negative tests for missing and malformed targets.

## Fix Focus Areas
- standards/scenarios.yaml[131-133]
- scripts/simulate-wave.py[167-185]
- scripts/validate.py[75-85]
- tests/test_validate.py[58-63]

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



Informational

5. Assertion count remains stale 🐞 Bug ⚙ Maintainability
Description
The PR adds five declarative assertions but leaves ADR-0015 claiming there are only 30, while the
scenario engine now reports 35. This immediately reintroduces the documentation drift the PR is
intended to correct.
Code

standards/scenarios.yaml[R131-133]

+      - {path: "standards/team-collaboration.yaml#teams.delivery_squad.lifecycle.trigger", op: contains, value: maintenance_wave.trigger}
+      - {path: "registry/teams/dev-wave.yaml#lifecycle.trigger", op: contains, value: maintenance_wave.trigger}
+      - {path: "standards/team-collaboration.yaml#interfaces.backlog.entry_schema", op: exists}
Relevance

●●● Strong

The PR explicitly claims 30→35 assertions, so correcting the stale ADR count is a direct
documentation fix.

PR-#10

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
S15 gains three assertions and S16 gains two, increasing the prior documented total from 30 to 35.
The ADR still states 30, while the engine computes the total directly from every scenario’s
asserts list.

standards/scenarios.yaml[126-148]
decisions/ADR-0015-scenario-engine.md[68-75]
scripts/simulate-wave.py[669-669]

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

## Issue description
ADR-0015 still reports 30 declarative assertions after this PR adds five.

## Issue Context
Update the ADR count to 35 so it matches the scenario registry and the engine’s computed summary.

## Fix Focus Areas
- decisions/ADR-0015-scenario-engine.md[68-75]
- standards/scenarios.yaml[126-148]

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


Grey Divider

Context sources
✅ Compliance rules (platform): 8 rules
✅ Web pages:
  +2 more
Review mode: ⚖️ Balanced: Downgraded extended -> standard: change is below the extended eligibility bar (hunks 10/18, lines 67/200; both must reach the floor). Router rationale: 跨多个声明、团队触发、账本、schema 与断言的行为契约变更,10 个独立编辑点存在多处易漏的跨文件对齐缺陷,冗余复核有实质价值。
ⓘ  4 issues published inline · 5 in summary

Grey Divider

Tip of the day
💡 Did you know, you can show, collapse, or hide each part of a finding: code, evidence, and all

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment on lines +25 to +26
"if": {"properties": {"disposition": {"const": "rejected"}}},
"then": {"required": ["reason"]}

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

1. Disposition conditions match absence 🐞 Bug ≡ Correctness

Both conditional schemas treat a missing disposition as a match, so an otherwise valid open entry
is incorrectly required to contain both reason and defer_condition. This makes the newly
declared backlog contract reject entries before producer-gate disposition.
Agent Prompt
## Issue description
The `rejected` and `deferred` JSON Schema conditions also match when `disposition` is absent, causing both conditional fields to become required.

## Issue Context
Under JSON Schema semantics, `properties` validates only properties that are present; it does not require `disposition` to exist. Each `if` must explicitly require the discriminator.

## Fix Focus Areas
- registry/schemas/backlog-entry.json[23-31]

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

Comment on lines +16 to +17
"evidence": {"type": "string", "description": "指标/证据/期望状态引用(issue 链接或 drift 报告锚点)"},
"expected_state_ref": {"type": "string", "description": "期望状态引用(governance/expected-state.json 锚点,drift 类必填)"},

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

2. Drift reference remains optional 🐞 Bug ≡ Correctness

Entries with source: drift can pass the schema without expected_state_ref, despite both the
schema description and issue lifecycle requiring that reference. Such entries lose the
expected-state anchor needed to triage and repair drift.
Agent Prompt
## Issue description
The schema describes `expected_state_ref` as mandatory for drift entries but never conditionally requires it.

## Issue Context
Add a discriminator condition for `source: drift`, including `required: [source]`, whose `then` requires `expected_state_ref`.

## Fix Focus Areas
- registry/schemas/backlog-entry.json[16-31]

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

Comment on lines +20 to +21
"reason": {"type": "string", "description": "disposition=rejected 时的驳回理由(必填)"},
"defer_condition": {"type": "string", "description": "disposition=deferred 时的机器可判定条件(必填;到期由 curator 机制扫描重排 top-k)"}

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

3. Empty disposition metadata accepted 🐞 Bug ≡ Correctness

The schema accepts reason: "" for rejected entries and defer_condition: "" for deferred entries
because both fields are unconstrained strings. These values satisfy required while violating the
lifecycle’s mandatory reason and machine-evaluable deferral condition.
Agent Prompt
## Issue description
Required disposition metadata can currently be empty and still satisfy the schema.

## Issue Context
At minimum, enforce non-empty values with `minLength`; define and validate a structured condition or expression grammar if `defer_condition` must be machine-evaluable.

## Fix Focus Areas
- registry/schemas/backlog-entry.json[18-21]
- registry/schemas/backlog-entry.json[23-31]

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

Comment thread standards/scenarios.yaml
- {path: "standards/flows.yaml#maintain_loop.maintenance_wave.acceptance", op: contains, value: pre_approved}
- {path: "standards/team-collaboration.yaml#teams.delivery_squad.lifecycle.trigger", op: contains, value: maintenance_wave.trigger}
- {path: "registry/teams/dev-wave.yaml#lifecycle.trigger", op: contains, value: maintenance_wave.trigger}
- {path: "standards/team-collaboration.yaml#interfaces.backlog.entry_schema", op: exists}

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. Schema assertion checks only scalar 🐞 Bug ☼ Reliability

The new S15 assertion verifies only that entry_schema contains a non-null scalar, not that the
referenced file exists or parses as JSON Schema. Deleting, misspelling, or corrupting
backlog-entry.json therefore leaves the advertised anti-regression scenario and repository
validator green.
Agent Prompt
## Issue description
The regression assertion checks the reference key but never resolves or validates its target.

## Issue Context
Resolve `interfaces.backlog.entry_schema` within the repository, reject escaping or missing paths, parse the target as JSON, and validate it as a Draft 2020-12 schema. Add negative tests for missing and malformed targets.

## Fix Focus Areas
- standards/scenarios.yaml[131-133]
- scripts/simulate-wave.py[167-185]
- scripts/validate.py[75-85]
- tests/test_validate.py[58-63]

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant