Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions BACKLOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ CC-001/CC-002 were consumed by PR #24 fix bundle inline, with no standalone entr
| CC-515 | ✅ closed 2026-07-29 | `gate_assurance_v3` immutable subject 與 artifact/subject/policy 三軸 shared verifier;downstream scope/closure producers 分屬 CC-518/CC-517 | arch/gate | 2026-07-23 | pr:#454 | P1 | design |
| CC-516 | ⏸ deferred | evidence-gated thin delivery wrapper 評估;只組合既有 primitives,不建立 workflow engine/FSM | ux/process | 2026-07-23 | — | P3 | spike |
| CC-517 | 🔵 active | maintainer `/ship`:primary review、structured remediation closure 與 conditional targeted confirmation | process/gate | 2026-07-23 | — | P1 | design |
| CC-518 | 🔵 active | gate scope manifest v1:immutable subject、changed paths、paired tests、signals 與 bounded expansion | ops/gate | 2026-07-23 | | P1 | design |
| CC-518 | ✅ closed 2026-07-29 | gate scope manifest v1:immutable subject、changed paths、paired tests、signals 與 bounded expansion | ops/gate | 2026-07-23 | pr:#455 | P1 | design |
| CC-519 | 🔵 active | selected-reviewer coverage/finding contract:declared coverage、stable IDs 與 actionable fix boundary | ops/gate | 2026-07-23 | — | P1 | design |
| CC-520 | 🔵 active | synthesis parity 與 remediation seed:findings union、root-cause grouping、coverage matrix 與 no-silent-drop | ops/gate | 2026-07-23 | — | P1 | design |
| CC-521 | 🔵 active | test-gap matrix、protocol recovery 與 live recall evaluation 分層 | ops/test | 2026-07-23 | — | P2 | design |
Expand Down Expand Up @@ -2021,7 +2021,9 @@ P1,排入 v0.11.0 delivery assurance correctness。

---

## CC-518 — gate scope manifest v1 🔵 active
## CC-518 — gate scope manifest v1 ✅ 2026-07-29

**See**: pr:#455

**Problem**: reviewers 目前主要從 diff list 與個別 prompt 探索 scope;renamed/
untracked paths、paired tests、sensitive signals 與 bounded adjacent context 沒有一份
Expand Down Expand Up @@ -2080,6 +2082,13 @@ early stop,finding 也常缺少受影響 behavior、fix boundary 與 verificat
5. schema/contract deterministic tests涵蓋 sequential logical sections、parallel
session evidence、blocker no-early-stop、missing checklist、invalid stable ID與
evidence-less blocker。
6. `gate_reviewer_result_v1.verdict` 是唯一 machine verdict;Markdown heading
只作 human presentation,重複或缺少 heading 不得讓已完成 review 變成格式失敗。
Shell 必須從已驗證 JSON verdict 機械聚合 GO/NO-GO,並與 final result parity。
7. Current scope manifests carry an immutable reviewer reference index with
repository path、subject/base snapshot、line count 與 content SHA-256。
Coverage evidence refs 與 finding source 必須命中該 index;不存在、scope 外或
超出 snapshot line count 的引用使 protocol `INCOMPLETE`。

**Done-when**: selected reviewer outputs 都是 schema-complete、coverage-declared,
且 finding 可直接作 remediation input;不對未選 reviewer 或模型 recall 作虛假保證。
Expand Down
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,24 @@ Versions follow [Semantic Versioning](https://semver.org/).

### Added

- **Selected-reviewer coverage and finding contract (CC-519).** Every selected
reviewer now emits a scope-bound `gate_reviewer_result_v1` JSON report with
an explicit eleven-surface checklist, evidence/reasons, stable finding IDs,
hard-gate/origin classification, affected behavior, failure mode, minimum
fix boundary, and verification expectation. The JSON verdict replaces
Markdown headings as the machine source of truth, so duplicate headings no
longer abort a completed review. Legacy role values such as `pass` are mapped
to the common enum in reviewer instructions, role-specific prose is confined
to rationale/findings, and diagnostics distinguish top-level, coverage,
finding, evidence-reference, and verdict failures. Current scope manifests
include a subject/base snapshot reference index with line counts and content
digests; nonexistent, out-of-scope, or out-of-range reviewer references fail
before synthesis. Missing/malformed sections, incomplete checklists, invalid
IDs, evidence-less blockers, and aggregate verdict drift fail closed as
protocol `INCOMPLETE`. Completed reports are preserved in
`pr_gate_result_v3`; v1/v2 and pre-index v3 results remain readable under
their legacy contracts.

- **Immutable gate scope manifest (CC-518).** `pmctl gate run` now creates a
content-addressed `gate_scope_manifest_v1` before reviewer dispatch, bound to
the immutable gate subject and linked from `gate_assurance_v3`. It declares
Expand Down
56 changes: 56 additions & 0 deletions DECISIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,62 @@ H2 標題格式:## YYYY-MM-DD: <短描述>
與 BACKLOG closure 對應的 entry,內文首行寫:Closes: BACKLOG.md#<PREFIX>-NNN
-->

## 2026-07-29: structured-reviewer-verdicts-replace-markdown-heading-parsing

Relates: CC-519

**Context**: Parallel reviewer sessions can finish their substantive work yet
cause the gate to stop before synthesis when Markdown headings are duplicated,
omitted, or reformatted. In one observed run, four reviewer artifacts repeated
the same canonical heading while their actual conclusions remained readable;
the operation correctly failed closed as protocol incomplete, but the heading
count neither represented reviewer coverage nor preserved an actionable,
machine-verifiable finding contract. Requiring another exact prose marker would
keep transport formatting coupled to review semantics. A later sequential run
exposed a second producer ambiguity: qa-tester used legacy `pass`,
architecture-reviewer added legacy `alignment`, and security/risk reviewers put
legacy narrative prose in `verdict`. The verifier correctly stopped the run as
`INCOMPLETE`, but its generic coverage/finding diagnostic hid the actual verdict
and top-level-key violations.

**Decision**: Every selected reviewer emits one scope-bound
`gate_reviewer_result_v1` JSON object. It carries the complete declared-surface
checklist, stable actionable findings, and one closed-enum `verdict`.
`reviewer_result_v1.verdict` is the only canonical reviewer verdict; Markdown
headings are optional presentation and are ignored for machine decisions.
The gate shell validates every JSON report before synthesis, calculates
GO/NO-GO from those verdicts, preserves the original reports in
`pr_gate_result_v3`, and verifies the aggregate against the final result.
Sequential combined sessions and parallel per-reviewer sessions use the same
logical report contract; topology and independence remain separate assurance
coordinates. Current scope manifests also carry a content-addressed reviewer
reference index. Every coverage evidence path and finding source must resolve
to that declared subject/base snapshot, and a line reference cannot exceed the
indexed line count. The manifest itself is admitted by its verified artifact
digest; arbitrary or nonexistent repository paths fail before synthesis.

**Alternatives considered**: (a) Continue requiring exactly one Markdown
heading——否決,duplicate/missing prose remains a false protocol failure after
substantive review completes. (b) Loosen the heading regex and take the first
match——否決,conflicting later text could be silently discarded. (c) Let
synthesis infer verdicts from prose——否決,synthesis is another model session
and cannot establish deterministic input parity.

**Constraints introduced**: Missing, duplicate, malformed, scope-digest-mismatched,
or coverage-incomplete JSON reports make the operation `INCOMPLETE`, not
reviewer `NO-GO`. A blocker cannot early-stop remaining coverage cells.
Pre-existing/caution findings cannot block, and a blocking finding requires
source evidence plus fix/verification boundaries. Coverage declaration does
not guarantee semantic completeness or model recall. Legacy result v1/v2
artifacts remain readable but cannot claim selected-reviewer protocol evidence.
Legacy role vocabulary must be mapped into the closed common verdict enum, role
narrative belongs in `rationale` or findings, and verifier diagnostics must name
the failing contract component without reclassifying it as a reviewer verdict.
Legacy scope manifests without a reference index remain readable for historical
result verification; current producers always emit the index and enforce it.

---

## 2026-07-28: gate-assurance-v3-separates-validity-freshness-applicability

Relates: CC-515
Expand Down
2 changes: 1 addition & 1 deletion MILESTONES.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@

| 票 | 摘要 | 狀態 |
|----|------|------|
| CC-518 | `gate_scope_manifest_v1`:immutable subject、changed/renamed/untracked、paired tests、signals、bounded expansion/truncation | 🔵 |
| CC-518 | `gate_scope_manifest_v1`:immutable subject、changed/renamed/untracked、paired tests、signals、bounded expansion/truncation | ✅ pr:#455 |
| CC-519 | selected-reviewer coverage/finding contract;sequential logical sections 與 parallel session isolation 分開 | 🔵 |
| CC-520 | synthesis findings-union parity、root-cause grouping、coverage matrix、remediation seed、no silent drop | 🔵 |
| CC-521 | actionable test-gap matrix + bounded protocol recovery;seeded live recall 僅作 quality evaluation | 🔵 |
Expand Down
20 changes: 18 additions & 2 deletions agents/architecture-reviewer.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ tools: Read, Bash, Glob, Grep

# Output brevity

Output is parsed by the main thread, not read directly by the user. No preamble, no closing summary — the structured YAML block is the complete response. English only. Each finding field (`issue`, `suggest`): one sentence max.
Output is parsed by the main thread, not read directly by the user. No preamble, no closing summary — the structured contract selected by the caller is the complete response. English only. Each finding field (`issue`, `suggest`): one sentence max.

Judge whether a change *fits* the module, the layer, the system as-is.

Expand Down Expand Up @@ -34,10 +34,26 @@ Out of scope: style (critic), security/risk (separate), tests (qa-tester), featu
1. Read brief + `git -C <repo> diff`.
2. Read what *was* the design: `ARCHITECTURE.md` if present, the changed module's directory layout, how peers handle similar concerns.
3. Use the canonical-memory provenance/context supplied by the gate brief for prior decisions that bind this change. Never infer a host-local memory path; if the brief reports unavailable or query-failed, state that limitation rather than falling back.
4. Note in `alignment` that no `conceptual_map` was provided; the review fell back to diff inspection.
4. Note in the contract `rationale` (or legacy `alignment` when no shared
contract is supplied) that no `conceptual_map` was provided and the review
fell back to diff inspection.

# Output

When the caller supplies the shared `reviewer_result_v1` contract, it fully replaces the legacy format below. Emit exactly one fenced JSON object with only
the nine contract keys (`kind`, `schema_version`, `reviewer`,
`scope_manifest_sha256`, `coverage_claim`, `coverage`, `findings`, `verdict`,
`rationale`). Complete every declared coverage surface even after finding a
blocker and map structural concerns/suggested boundaries to the common
actionable finding fields. `verdict` must be exactly
`approve|advise|block-soft|block`; put alignment prose in `rationale`.
Evidence paths must come from the caller's declared reference index, with line
numbers inside the indexed snapshot. Do not
add `status`, `summary`, or `alignment` as top-level keys. Every finding ID uses
the exact `architecture-reviewer-FNNN` prefix. Do not emit separate legacy
YAML. Only when the caller does not supply that contract, use the legacy
standalone format below.

```
status: approve | advise | block-soft
summary: <one line>
Expand Down
15 changes: 14 additions & 1 deletion agents/critic.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ tools: Read, Bash, Glob, Grep

# Output brevity

Output is parsed by the main thread, not read directly by the user. No preamble, no closing summary — the structured YAML block is the complete response. English only. Each finding field (`issue`, `suggest`): one sentence max.
Output is parsed by the main thread, not read directly by the user. No preamble, no closing summary — the structured contract selected by the caller is the complete response. English only. Each finding field (`issue`, `suggest`): one sentence max.

Find what's wrong, weak, or missed. Do not validate.

Expand All @@ -28,6 +28,19 @@ Find what's wrong, weak, or missed. Do not validate.

# Output

When the caller supplies the shared `reviewer_result_v1` contract, it fully replaces the legacy format below. Emit exactly one fenced JSON object with only
the nine contract keys (`kind`, `schema_version`, `reviewer`,
`scope_manifest_sha256`, `coverage_claim`, `coverage`, `findings`, `verdict`,
`rationale`). Complete every declared coverage surface even after finding a
blocker and map `issue` to the common actionable finding fields. `verdict` must
be exactly `approve|advise|block-soft|block`; put explanatory prose in
`rationale`. Evidence paths must come from the caller's declared reference
index, with line numbers inside the indexed snapshot. Every finding ID uses
the exact `critic-FNNN` prefix. Do not add
`status`, `summary`, `over_scope`, or `missed` as
top-level keys and do not emit separate legacy YAML. Only when the caller does
not supply that contract, use the legacy standalone format below.

```
status: approve | advise | block-soft
summary: <one line>
Expand Down
18 changes: 17 additions & 1 deletion agents/qa-tester.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ tools: Read, Edit, Write, Bash, Glob, Grep

# Output brevity

Output is parsed by the main thread, not read directly by the user. No preamble, no closing summary — the structured YAML block is the complete response. English only. Each finding field: one sentence max.
Output is parsed by the main thread, not read directly by the user. No preamble, no closing summary — the structured contract selected by the caller is the complete response. English only. Each finding field: one sentence max.

Testing rules — categories, layer choice, anti-patterns — come from the configured QA rules directory, not your training data.

Expand Down Expand Up @@ -62,6 +62,22 @@ Run A if no tests exist, then B. End state: runnable suite with explicit categor

# Output

When the caller supplies the shared `reviewer_result_v1` contract, it fully replaces the legacy format below. Emit exactly one fenced JSON object with only
the nine contract keys (`kind`, `schema_version`, `reviewer`,
`scope_manifest_sha256`, `coverage_claim`, `coverage`, `findings`, `verdict`,
`rationale`). Complete every declared coverage surface even after finding a
blocker and map test gaps/audit findings to the common actionable finding
fields. `verdict` must be exactly `approve|advise|block-soft|block`: map legacy
`pass` to `approve` and a gate-blocking `needs-tests` outcome to `block`; put
matrix/run/audit details in `rationale` or common findings. Evidence paths must
come from the caller's declared reference index, with line numbers inside the
indexed snapshot. Never emit `pass`,
`needs-tests`, or prose as the JSON verdict. Every finding ID uses the exact
`qa-tester-FNNN` prefix. Do not add `status`, `summary`, `matrix`, `run`, or
`audit_findings` as top-level keys and do not emit separate legacy YAML. Only
when the caller does not supply that contract, use the legacy standalone
format below.

```
status: pass | block | needs-tests
summary: <one line>
Expand Down
18 changes: 17 additions & 1 deletion agents/risk-reviewer.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ tools: Read, Bash, Glob, Grep

# Output brevity

Output is parsed by the main thread, not read directly by the user. No preamble, no closing summary — the structured YAML block is the complete response. English only. Each finding field (`risk`, `failure_mode`, `fix`): one sentence max.
Output is parsed by the main thread, not read directly by the user. No preamble, no closing summary — the structured contract selected by the caller is the complete response. English only. Each finding field (`risk`, `failure_mode`, `fix`): one sentence max.

HARD GATE. Think about what happens if the change is wrong, not whether it's conceptually correct (that's critic / architecture / security territory).

Expand Down Expand Up @@ -37,6 +37,22 @@ A `block` halts the PR until either (1) code/process is fixed (re-review) or (2)

# Output

When the caller supplies the shared `reviewer_result_v1` contract, it fully replaces the legacy format below. Emit exactly one fenced JSON object with only
the nine contract keys (`kind`, `schema_version`, `reviewer`,
`scope_manifest_sha256`, `coverage_claim`, `coverage`, `findings`, `verdict`,
`rationale`). Complete every declared coverage surface even after finding a
blocker and map risk/failure mode/mitigation to the common actionable finding
fields. `verdict` must be exactly `approve|advise|block-soft|block`: map legacy
`pass` and `pass-not-applicable` to `approve`, and put reversibility/override
prose in `rationale` or the common finding fields. Evidence paths must come
from the caller's declared reference index, with line numbers inside the
indexed snapshot. Never emit `pass`,
`pass-not-applicable`, or prose as the JSON verdict. Do not add `status`,
`summary`, `reversibility`, or `override_path` as top-level keys. Every finding
ID uses the exact `risk-reviewer-FNNN` prefix, never `risk-FNNN`. Do not emit
separate legacy YAML. Only when the caller does not supply that contract, use
the legacy standalone format below.

```
status: pass | block | pass-not-applicable
summary: <one line>
Expand Down
17 changes: 16 additions & 1 deletion agents/security-reviewer.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ tools: Read, Bash, Glob, Grep

# Output brevity

Output is parsed by the main thread, not read directly by the user. No preamble, no closing summary — the structured YAML block is the complete response. English only. Each finding field (`issue`, `impact`, `fix`): one sentence max.
Output is parsed by the main thread, not read directly by the user. No preamble, no closing summary — the structured contract selected by the caller is the complete response. English only. Each finding field (`issue`, `impact`, `fix`): one sentence max.

HARD GATE. A `block` halts the PR until either (1) code is fixed (re-review) or (2) the user explicitly overrides with recorded justification.

Expand Down Expand Up @@ -37,6 +37,21 @@ HARD GATE. A `block` halts the PR until either (1) code is fixed (re-review) or

# Output

When the caller supplies the shared `reviewer_result_v1` contract, it fully replaces the legacy format below. Emit exactly one fenced JSON object with only
the nine contract keys (`kind`, `schema_version`, `reviewer`,
`scope_manifest_sha256`, `coverage_claim`, `coverage`, `findings`, `verdict`,
`rationale`). Complete every declared coverage surface even after finding a
blocker and map security impact/remediation to the common actionable finding
fields. `verdict` must be exactly `approve|advise|block-soft|block`: map legacy
`pass` and `pass-not-applicable` to `approve`, and put explanatory prose in
`rationale`. Evidence paths must come from the caller's declared reference
index, with line numbers inside the indexed snapshot. Never emit `pass`,
`pass-not-applicable`, or prose as the JSON
verdict. Every finding ID uses the exact `security-reviewer-FNNN` prefix. Do
not add `status`, `summary`, or `override_path` as top-level keys and do not
emit separate legacy YAML. Only when the caller does not supply that contract,
use the legacy standalone format below.

```
status: pass | block | pass-not-applicable
summary: <one line>
Expand Down
Loading