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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ pm/rollup/.PORTFOLIO.md.*
# Repo-local pm-dispatch state (context index, trace events)
# Set PM_DISPATCH_STATE_ROOT=.pm-dispatch to use this location.
.pm-dispatch/
# Sandbox-local durable state used by ship worktree lanes.
.pm-dispatch-state/
# SQLite context index files — global scope is intentional: covers custom
# PM_DISPATCH_STATE_ROOT paths inside the repo in addition to .pm-dispatch/.
*.db
Expand Down
308 changes: 290 additions & 18 deletions BACKLOG.md

Large diffs are not rendered by default.

24 changes: 15 additions & 9 deletions DECISIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ CC-520, CC-521

> 2026-07-27 clarification:本條目的 `targeted`-as-tier 部分已由
> `targeted-review-is-a-pass-kind-not-a-tier` 取代;其餘六維正交決策不變。
>
> 2026-07-28 clarification:mode 是使用者擁有的成本/獨立性選擇。policy 只輸出
> recommendation;使用者未指定時才自動採用,明確 sequential/parallel 永遠優先。
> recommendation divergence 只記錄於 evidence,不是 downgrade,也不需要 override。

**Context**: 現有 runtime 已將 tier detection、reviewer selection 與
`SEQUENTIAL=true|false` 分開處理,但 review 文件與規畫曾把 `full`、五個 reviewers、
Expand All @@ -70,15 +74,16 @@ local closure、targeted confirmation 或拆票,但不建立新的 gate 或 wo
1. **Tier** 表示審查深度與 evidence floor(express/standard/full/targeted),不決定
execution topology。
2. **Mode** 表示 sequential combined session 或 parallel per-reviewer sessions;
不提升 tier,也不保證 reviewer coverage。policy 可分別輸出 recommended mode
required mode。
不提升 tier,也不保證 reviewer coverage。policy 輸出 recommended mode
明確 user choice 優先,只有 omitted mode 才採 recommendation
3. **Reviewer coverage/independence** 記錄實際 selected/skipped reviewers、
implementation-context isolation 與 reviewer-to-reviewer context model;不得由
tier 或 reviewer 數量推論。
4. **Policy classification** 由 canonical resolver 根據 diff、brief、敏感 surface
與 override 算出 minimum tier、required reviewers、recommended/required mode
與 downgrade audit;generic `pmctl gate` risk-based policy 與 maintainer `/ship`
primary full-coverage policy分開。
與 override 算出 minimum tier、required reviewers、recommended mode、
mode selection source/recommendation divergence 與 downgrade audit;generic
`pmctl gate` risk-based policy 與 maintainer `/ship` primary full-coverage
policy分開。
5. **Artifact subject** 以 stable repository identity、base/head commit、tree
fingerprint 與 subject kind 說明 evidence 審查/測試了什麼;artifact validity、
subject freshness 與 consumer policy applicability 分開判斷。
Expand All @@ -87,10 +92,11 @@ local closure、targeted confirmation 或拆票,但不建立新的 gate 或 wo
+ closed remediation ledger + required targeted confirmations。branch/HEAD/tree、
manual evidence與 accepted-risk override 仍須符合 consumer policy。

合法組合包含 express/standard/full/targeted × sequential/parallel;只有 policy
明確要求 reviewer isolation 時 `required_mode: parallel` 才是 hard requirement。
Maintainer `/ship` 使用一次 primary comprehensive review、structured remediation
closure、必要時一次 targeted confirmation,再對 final tree 執行 affected/full tests。
合法組合包含 express/standard/full/targeted × sequential/parallel;policy 不得把
mode 變成 hard requirement。未指定時可自動採 recommendation,明確 user choice
不得被 resolver 改寫。Maintainer `/ship` 使用一次 primary comprehensive review、
structured remediation closure、必要時一次 targeted confirmation,再對 final tree
執行 affected/full tests。

**Alternatives considered**: (a) `full => parallel => five reviewers => publishable`
單一 profile——否決,因深度、拓撲、coverage 與發布證據是不同問題,且與現有 runtime
Expand Down
2 changes: 1 addition & 1 deletion MILESTONES.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@
| 票 | 摘要 | 狀態 |
|----|------|------|
| CC-512 | Slices A/B/C:coordinate sources/CLI resolution、machine-owned assurance envelope/evidence capture、shared verifier/parity ratchets;targeted 不再是 tier | ✅ pr:#451 |
| CC-513 | canonical resolver:minimum tier、required reviewers、recommended/required mode、generic vs maintainer policy 與 downgrade audit | 🔵 |
| CC-513 | canonical resolver:minimum tier、required reviewers、mode recommendation/user-choice provenance、generic vs maintainer policy 與 tier/coverage downgrade audit | 🔵 |
| CC-515 | immutable subject;artifact validity、subject freshness、policy applicability 三軸 shared verifier | 🔵 |

### Phase 8 — existing gate structured evidence
Expand Down
38 changes: 32 additions & 6 deletions commands/pr-gate.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,39 @@ argument-hint: "[express|standard|full] [--targeted r1,r2 --initial-result path]

Run the PR gate via `pmctl gate run`. The `runtime/bin/pr-gate.sh` script is the
internal implementation; `pmctl gate run` is the preferred invocation surface.
This command uses the `generic` consumer policy: one canonical resolver combines
the diff, trusted brief metadata, requested tier/mode/pass/coverage, and
repository policy before any reviewer is dispatched.

**Sequential mode (default):** all reviewers run in one combined session.
Low main-thread token cost (~5k dispatch + read result).
**Sequential mode (`--mode sequential`; `--sequential` is compatible):** all
reviewers run in one combined session. Lower token cost.

**Parallel mode (`--mode parallel`; `--parallel` is compatible):** each reviewer runs in its own independent session
followed by a PM synthesis session. Higher token cost — use for auth/payment/migration
paths or when reviewer independence matters.

When mode is omitted, policy automatically selects its recommendation from the
consumer and matched risk signals. Any explicit sequential or parallel choice
wins; the assurance records when that choice differs from the recommendation,
but does not treat it as a downgrade.

| Situation | Args |
|---|---|
| Routine code / seed / docs changes | _(none)_ |
| Re-gate after fixing specific findings | `--targeted qa-tester,risk-reviewer --initial-result <path>` |
| Auth / payment / migration / sensitive paths | `--mode parallel` |
| Force a specific tier | `express` / `standard` / `full` |
| Auth / payment / migration / sensitive paths | _(none; policy adds the matching reviewer and recommends parallel)_ |
| Input/evaluation/command execution boundary | _(none; policy recommends parallel)_ |
| Conserve reviewer-session token usage | `--mode sequential` |
| Request independent reviewer sessions | `--mode parallel` |
| Request a specific tier | `express` / `standard` / `full` (cannot lower the policy floor) |

A tier or reviewer-coverage policy rejection happens before reviewer dispatch
and is an execution/policy failure, not a `Final: NO-GO` reviewer verdict.
Scope-bound tier/coverage downgrades use the runtime's explicit structured
policy-override contract. Its scope fingerprint binds the actual tracked patch
plus in-scope untracked content, so an approval cannot be replayed after a
same-shape content change. `.gate-overrides.md` only supplies reviewer finding
context and cannot lower policy.

## Step 1 - Invoke pmctl directly

Expand Down Expand Up @@ -179,7 +198,7 @@ SCOPE="${SCOPE_TOKENS[*]:-}"
# `pmctl:*` prefix match. The quotes around the placeholder keep this block
# valid, executable Bash even before that substitution (bare, unquoted
# `<work_dir>` would be parsed as I/O redirection and fail to parse).
GATE_ARGS=(--cd "<work_dir>" --executor "$GATE_EXECUTOR")
GATE_ARGS=(--cd "<work_dir>" --executor "$GATE_EXECUTOR" --policy generic)
[[ -n "$GATE_MODEL" ]] && GATE_ARGS+=(--model "$GATE_MODEL")
[[ -n "$TIER_OVERRIDE" ]] && GATE_ARGS+=(--tier "$TIER_OVERRIDE")
[[ -n "$TARGETED_REVIEWERS" ]] && GATE_ARGS+=(--targeted "$TARGETED_REVIEWERS" --initial-result "$INITIAL_RESULT")
Expand Down Expand Up @@ -289,14 +308,21 @@ When the `pmctl gate wait` background Bash completion notification arrives:
and matching canonical terminal run records. The producer publishes the
sidecar before the v2 result that references it; verification briefly
retries when it observes an in-flight v2 result before its protected
attestation rename completes.
attestation rename completes. Current envelopes also carry the shell-owned
policy resolution (classification, matched signals, floors, resolved
coordinates, and override provenance); earlier v2 envelopes without that
optional block remain readable.
5. Prepend `PR-gate complete.` to completion relay and include the full gate
result (including `Final: GO` / `Final: NO-GO`) unchanged.
6. On failure, avoid collapsing findings; relay the actual stderr summary and
exit 0 from `/pm` only if needed by the conversation protocol.

## Local verification after gate findings

For a follow-up gate after a complete analysis or `Final: NO-GO`, preserve the
user's explicit `--mode sequential` or `--mode parallel` choice. Omit the flag
only when the user has not chosen a mode and wants policy to infer it again.

After fixing a NO-GO finding, run only the affected tests before re-gating:

```bash
Expand Down
10 changes: 7 additions & 3 deletions commands/ship.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,13 @@ using the authoritative [gate model diversity policy](../docs/review-model.md#ga
Base the choice on actual model identities, record both identities in the
handoff, and keep the same resolved pair for targeted re-runs. Add
`--model "<gate_model>"` below only when the executor default does not already
resolve to the selected gate model.
resolve to the selected gate model. Mode is user-owned: append the literal
`--mode sequential` when token budget favors one combined reviewer session, or
`--mode parallel` when independent sessions are desired. If neither is present,
the gate auto-selects the policy recommendation. Preserve the user's explicit
choice on targeted re-runs unless the user changes it.

Run `pmctl gate run --executor <gate_executor> --cd "<work_dir>" --lifecycle foreground`
Run `pmctl gate run --executor <gate_executor> --policy maintainer --cd "<work_dir>" --lifecycle foreground`
(substitute `<work_dir>` with the literal absolute working directory, not
`"$PWD"` — a shell-variable expansion makes the command unanalyzable
statically and forces a manual approval every time even though a bare
Expand Down Expand Up @@ -172,7 +176,7 @@ once the call returns.
preserve the established structure, such as wording/comments, a narrow
assertion or fixture adjustment, or a small guard/error-handling fix.

Then re-run `pmctl gate run --executor <gate_executor> --cd "<work_dir>"
Then re-run `pmctl gate run --executor <gate_executor> --policy maintainer --cd "<work_dir>"
--lifecycle foreground --targeted <reviewer,...> --initial-result
"<initial_gate_result_path>"` (same literal-path substitution as Step 3's
first call — never `"$PWD"`). The initial-result path is the comprehensive
Expand Down
12 changes: 12 additions & 0 deletions core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,18 @@ This directory contains the canonical PM-runtime data contract. **`core/` is def
(`~/.local/share/pm-dispatch/state/`). **Definitions, not the writer.**
- `context-pack/` — source-interface contract for ContextPack assembly.

Gate assurance definitions are split deliberately:

- `policy/gate-tiers.tsv`, `gate-modes.tsv`, and `gate-pass-kinds.tsv` define
the independent assurance coordinates.
- `policy/gate-policy-consumers.tsv` and `gate-policy-signals.tsv` define
consumer-specific coverage and deterministic risk floors.
- `schema/gate-policy-override.schema.json` defines explicit scope-bound user
approval for a tier or reviewer-coverage downgrade; mode remains a direct
user choice.
- `schema/gate-assurance.schema.json` defines the portable envelope that records
both resolved coordinates and the policy resolution that produced them.

## Invariants

1. **`core/*` may NOT import / reference `runtime/`, `scripts/`, `adapters/`,
Expand Down
7 changes: 4 additions & 3 deletions core/policy/gate-modes.tsv
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Gate execution topology. Mode does not imply tier or reviewer coverage.
mode topology synthesis is_default
sequential combined-session inline true
parallel per-reviewer-sessions separate-session false
# Omitted mode is resolved from policy recommendations, not from this table.
mode topology synthesis
sequential combined-session inline
parallel per-reviewer-sessions separate-session
6 changes: 6 additions & 0 deletions core/policy/gate-policy-consumers.tsv
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Gate policy consumers. Mode is inferred from recommended_mode only when the user does not select one explicitly.
policy_pass policy pass_kind minimum_tier required_reviewers recommended_mode
generic:initial generic initial express critic,qa-tester sequential
generic:targeted generic targeted express none sequential
maintainer:initial maintainer initial express critic,qa-tester,architecture-reviewer,security-reviewer,risk-reviewer parallel
maintainer:targeted maintainer targeted express none parallel
18 changes: 18 additions & 0 deletions core/policy/gate-policy-signals.tsv
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Gate policy signals. Reviewer requirements apply to initial discovery; targeted passes retain tier/mode signals but use requested remediation coverage.
signal match_source pattern minimum_tier required_reviewers recommended_mode
docs-only classification docs-only express none sequential
bounded-runtime classification bounded-runtime express none sequential
medium-change classification medium-change standard architecture-reviewer parallel
large-change classification large-change full critic,qa-tester,architecture-reviewer,security-reviewer,risk-reviewer parallel
binary-change classification binary-change standard architecture-reviewer parallel
renamed-input classification renamed express none sequential
untracked-input classification untracked express none sequential
generated-input classification generated express none sequential
cross-boundary classification cross-boundary standard architecture-reviewer parallel
security-sensitive-path path-regex (^|[/_.-])(auth|oauth|jwt|sessions?|secrets?|passwords?|tokens?|credentials?|cors|csrf|webhooks?|sudo|ssh|payments?|billing)([/_.-]|$) express security-reviewer parallel
input-execution-path path-regex (^|[/_.-])(eval|exec|execute|command|shell|hook|guard|allowlist)([/_.-]|$)|(^|/)(\.github|workflows?|ci)(/|$) standard security-reviewer parallel
risk-sensitive-path path-regex (^|[/_.-])(migrations?|migrate|destructive|deletions?|delete|removals?|remove|rollback|concurrency|concurrent|race|locks?|cancel|reconcile)([/_.-]|$) express risk-reviewer parallel
public-contract-path path-regex (^|/)(cli|commands|skills|core/schema)(/|$)|(^|[/_.-])(apis?|schemas?|contracts?)([/_.-]|$) standard architecture-reviewer parallel
policy-source-path path-regex (^|/)core/policy(/|$) full architecture-reviewer,security-reviewer,risk-reviewer parallel
brief-architecture-minor brief-value minor standard architecture-reviewer parallel
brief-architecture-major brief-value major full critic,qa-tester,architecture-reviewer,security-reviewer,risk-reviewer parallel
Loading