version: 1.1.0
updated: 2026-10-07
owner: delivery flow
description: >
  Delivery-flow rules derived from the metrics Valven reports per team and per
  developer: cycle time, rework rate, review responsiveness, PR complexity,
  commit risk, lead time for changes and change failure rate. The Development
  Behaviors bands (churn, coding, pickup and review time) are Valven's own scoring
  table; every other threshold is a stated default, because Valven publishes no
  formula for it. prefs.global.valven.thresholds overrides any of them.

# The whole change set is in scope: these rules judge the shape of a pull
# request, not the language inside it. Generated output, lockfiles and recorded
# snapshots are removed first by schemas/review-file-exclusions.json, so a
# regenerated client never counts toward a size budget.
scope:
  paths: ["**"]
  notCovered:
    code-quality: language rules live in the stack registries (ios-coding-standard and the like)

severity_levels: [blocking, important, suggestion]
enforcement_kinds:
  gate: measured by scripts/valven-gate.mjs from the diff, the commits, the branch name and the PR body
  judgement: requires a reviewer

# Measured rules. valven-gate.mjs reads this block; skill-conformance.mjs does
# not, so reviewers are never asked for a verdict on something a script counts.
# `modes` names the pipeline points the rule runs at: dev (Phase 2 exit), commit
# (Phase 4 before push) and review (Phase 3 and /multi-agent:review).
gate_rules:
  - id: VLV-SIZE-01
    title: A pull request changes at most 250 human-authored lines; past 600 it cannot merge as one
    metric: PR Complexity, Cycle Time, Review Responsiveness
    severity: important
    important_over: 250
    blocking_over: 600
    modes: [dev, commit, review]
    fix: split the branch into stacked pull requests with scripts/valven-split.mjs
  - id: VLV-SIZE-02
    title: A pull request touches at most 25 human-authored files
    metric: PR Complexity, Commit Risk Score
    severity: important
    important_over: 25
    modes: [dev, commit, review]
    fix: split the branch into stacked pull requests with scripts/valven-split.mjs
  - id: VLV-SCOPE-01
    title: Renames and moves do not share a pull request with content changes
    metric: PR Complexity, Rework Rate
    severity: important
    renames_at_least: 3
    content_lines_over: 50
    modes: [dev, commit, review]
    fix: ship the renames as their own pull request first; valven-split.mjs puts them in slice 1
  - id: VLV-TEST-01
    title: A change to source code carries a change to its tests
    metric: Change Failure Rate, Rework Rate
    severity: important
    modes: [dev, commit, review]
    fix: add or update the test that exercises the changed behaviour
  - id: VLV-TRACE-01
    title: The branch name carries the issue key
    metric: Cycle Time, Lead Time for Changes
    severity: important
    key_pattern: "[A-Z][A-Z0-9]+-[0-9]+"
    modes: [dev, commit, review]
    fix: rename the branch to feature/<KEY>-<id> or bugfix/<KEY>-<id>
  - id: VLV-TRACE-02
    title: Every commit subject carries the issue key
    metric: Cycle Time, Lead Time for Changes
    severity: important
    key_pattern: "[A-Z][A-Z0-9]+-[0-9]+"
    modes: [commit, review]
    fix: reword the commits so each subject ends with [<KEY>-<id>]
  - id: VLV-COMMIT-01
    title: No WIP, fixup, squash or temp commits reach the pull request
    metric: Commit Risk Score, Rework Rate
    severity: important
    subject_pattern: "^(wip\\b|fixup!|squash!|amend!|temp\\b|tmp\\b)"
    modes: [commit, review]
    fix: squash them into the commit they amend before pushing
  - id: VLV-REWORK-01
    title: At most 30% of the removed lines were written in the last 21 days
    metric: Rework Rate, Churn rate (Development Behaviors, scored 100 - churn %)
    severity: important
    ratio_over: 0.30
    window_days: 21
    min_removed_lines: 20
    modes: [dev, commit, review]
    fix: settle the requirement before rewriting; if the earlier code was wrong, say so in the PR body
  - id: VLV-PRDESC-01
    title: The PR body exists, is at least 80 characters and says how the change was tested
    metric: Review Responsiveness, Cycle Time
    severity: important
    min_chars: 80
    test_pattern: "(test|verified|how to verify|nasıl test)"
    modes: [review]
    fix: add what changed, why, and how it was tested; attach a screenshot for UI changes
  - id: VLV-HOTFIX-01
    title: A hotfix branch changes at most 150 human-authored lines
    metric: Mean Time To Recover, Change Failure Rate
    severity: important
    important_over: 150
    branch_pattern: "^hotfix/"
    modes: [dev, commit, review]
    fix: keep the fix to the incident; move everything else to a follow-up pull request
  - id: VLV-AGE-01
    title: No commit in the pull request is older than 14 days
    metric: Lead Time for Changes, Cycle Time
    severity: important
    days_over: 14
    modes: [dev, commit, review]
    fix: start a fresh branch from the current base, carry the change with scripts/valven-port.mjs, open a new PR and close this one
  - id: VLV-BEHIND-01
    title: The branch is at most 50 commits behind its base and its merge-base is at most 14 days old
    metric: Lead Time for Changes, Change Failure Rate
    severity: important
    behind_over: 50
    base_days_over: 14
    modes: [dev, commit, review]
    fix: carry the change onto a fresh branch from the current base with scripts/valven-port.mjs
  - id: VLV-TRACE-03
    title: Every commit carries the same issue key as the branch
    metric: PR Complexity, Lead Time for Changes
    severity: important
    key_pattern: "[A-Z][A-Z0-9]+-[0-9]+"
    modes: [commit, review]
    fix: move the commits of the other issue to their own branch and PR

  # Development Behaviors: cycle time breakdown. Each duration is scored into
  # Valven's bands (100 / 75 / 50 / 0; every bound exclusive). A score of 50 or
  # 0 is reported as a suggestion: the time has already passed, so the pull
  # request cannot fix it, and the finding names the habit that does. Deploy
  # time is not a rule: a release train or a store review sets it, not the
  # pull request.
  - id: VLV-CYCLE-01
    title: Coding time, from the first commit to opening the pull request, stays under 2.5 hours
    metric: Cycle Time (coding)
    severity: suggestion
    full_under_minutes: 30
    three_quarter_under_minutes: 150
    half_under_minutes: 1440
    modes: [commit, review]
    fix: open the pull request as soon as the first slice works; ship the next slice as its own pull request
  - id: VLV-CYCLE-02
    title: Pickup time, from ready-for-review to the first review, stays under 3 hours
    metric: Cycle Time (pickup), Review Responsiveness
    severity: suggestion
    full_under_minutes: 60
    three_quarter_under_minutes: 180
    half_under_minutes: 840
    modes: [review]
    fix: assign the reviewers when the pull request opens; reviewers check their queue at fixed times every day
  - id: VLV-CYCLE-03
    title: Review time, from the first review to approval, stays under 3 hours
    metric: Cycle Time (review), Review Responsiveness
    severity: suggestion
    full_under_minutes: 30
    three_quarter_under_minutes: 180
    half_under_minutes: 1080
    modes: [review]
    fix: answer every comment the same day in one round and push the fixes together
  # A missing reviewer is important: the author fixes it now. A long-lived
  # draft is a suggestion, because an unattended run opens a draft on purpose
  # and a person decides when it is ready.
  - id: VLV-PICKUP-01
    title: A pull request has a reviewer and does not sit as a draft for more than 3 hours
    metric: Cycle Time (pickup), Review Responsiveness
    severity: important
    draft_minutes_over: 180
    draft_severity: suggestion
    modes: [review]
    fix: assign the default reviewers; mark the pull request ready for review once its gates pass, or close it

# Judgement rules. skill-conformance.mjs selects these for every diff, so each
# reviewer returns a verdict per ID.
rules:
  - id: VLV-SCOPE-02
    title: The pull request does one thing; a feature, a refactor and a fix are separate pull requests
    severity: important
    enforcement: judgement
    rationale: mixed pull requests are the main input to PR Complexity and Rework Rate
  - id: VLV-PRDESC-02
    title: The PR body explains why the change exists and how a reviewer verifies it
    severity: important
    enforcement: judgement
    rationale: review waiting time drops when the reviewer does not have to reconstruct the intent
