Skip to content

Latest commit

 

History

History
157 lines (140 loc) · 7.44 KB

File metadata and controls

157 lines (140 loc) · 7.44 KB

LOOP.md

This file is the source of truth for loop configuration. loop-audit reads it to compute readiness level; loops themselves read it to know their gate thresholds, schedule, and escalation path. Keep it in version control — changes to gate thresholds should go through the same review as code.

# ──────────────────────────────────────────────────────────────
# 1. LOOP DEFINITIONS
# Each loop declares its readiness level, what triggers it, and
# where its skill/config lives. Fill in the 4 unnamed loops.
# ──────────────────────────────────────────────────────────────
loops:
  - id: loop-triage
    level: L0
    enabled: true
    skill: .grok/skills/loop-triage/SKILL.md
    trigger:
      type: schedule
      cron: "0 8 * * 1-5"          # 08:00 weekdays, repo-local timezone
      on_demand: true               # can also be run manually
    timeout_minutes: 10
    output: appended to STATE.md under `## Triage Log`

  - id: loop-verifier
    level: L1
    enabled: false                  # flips true once L1 gate is cleared
    skill: .grok/skills/loop-verifier/SKILL.md
    trigger:
      type: event
      on: [triage_completed]        # runs immediately after triage, not on its own schedule
    timeout_minutes: 15
    output: pass/fail verdict appended to STATE.md, see Verifier Contract below

  - id: minimal-fix
    level: L2
    enabled: false
    skill: .grok/skills/minimal-fix/SKILL.md
    trigger:
      type: event
      on: [verifier_passed]
    timeout_minutes: 20
    output: proposed diff, opened as draft PR — never auto-merged at L2

  - id: [loop-name-5]
    level: [L_]
    enabled: false
    skill: .grok/skills/[loop-name-5]/SKILL.md
    trigger:
      type: [schedule|event]
      cron: [if schedule]
      on: [if event]
    timeout_minutes: [N]
    output: [what it writes and where]

  - id: [loop-name-6]
    level: [L_]
    enabled: false
    skill: .grok/skills/[loop-name-6]/SKILL.md
    trigger: {}
    output: []

  - id: [loop-name-7]
    level: [L_]
    enabled: false
    skill: .grok/skills/[loop-name-7]/SKILL.md
    trigger: {}
    output: []

# ──────────────────────────────────────────────────────────────
# 2. READINESS GATES
# Numeric thresholds an audit checks against to recommend the
# next level. loop-audit reads these directly — don't hardcode
# thresholds anywhere else.
# ──────────────────────────────────────────────────────────────
gates:
  L0_to_L1:
    require: consecutive_clean_triage_runs >= 10
    false_positive_rate_max: 0.05   # over the same window

  L1_to_L2:
    require: consecutive_verified_runs >= 10
    verifier_false_negative_rate_max: 0.0   # zero tolerance — a missed failure here is the riskiest failure mode

  L2_to_L3:
    require: human_approved_fix_proposals >= 15
    rollback_count_max: 0           # any rollback resets this counter to 0
    scope: per_fix_category          # L3 is granted per category, not globally — see rollback rules

# ──────────────────────────────────────────────────────────────
# 3. VERIFIER CONTRACT
# What loop-verifier must guarantee to be trusted as a gate.
# If you swap in a different verifier, it must still satisfy this.
# ──────────────────────────────────────────────────────────────
verifier_contract:
  input: triage findings from the immediately preceding loop-triage run (STATE.md `## Triage Log`, latest entry)
  output:
    format: structured verdict, one of [pass, fail, inconclusive]
    must_include:
      - verdict
      - reasoning (why pass/fail — not just the label)
      - confidence_score (0.0–1.0)
      - timestamp
  idempotency: running the verifier twice on the same triage output must produce the same verdict
  inconclusive_handling: treated as fail for gate-counting purposes — never silently dropped
  on_fail: loop chain stops here; minimal-fix does not run; STATE.md open item created automatically

# ──────────────────────────────────────────────────────────────
# 4. ROLLBACK RULES (L3 auto-fix stage)
# These apply once a fix category has cleared the L2→L3 gate and
# auto-merge is live for that category.
# ──────────────────────────────────────────────────────────────
rollback:
  triggers:
    - post_merge_test_failure        # CI red on main after an auto-merged fix
    - error_rate_spike_pct: 5         # >5% increase in monitored error rate within rollback_window
    - manual_revert_requested         # any owner can force this, no quorum needed
  rollback_window_minutes: 30         # how long after merge a spike/failure counts as caused by the fix
  mechanism: git revert (not force-push) — preserves history and triggers a fresh CI run
  on_rollback:
    - immediately disable auto-merge for the affected fix_category
    - reset that category's L3 counter (see gates.L2_to_L3.rollback_count_max) to 0
    - require [N] re-cleared L2 cycles before that category is eligible for L3 again
    - log to STATE.md under `## Rollback Log` with: timestamp, fix_category, trigger, who/what reverted it
  cool_down_minutes: 60               # no new auto-merges for the same category during this window post-rollback

# ──────────────────────────────────────────────────────────────
# 5. OWNERSHIP & ESCALATION
# CODEOWNERS routes PR review. This section defines what happens
# when a loop itself fails, times out, or needs a human decision —
# distinct from normal code review.
# ──────────────────────────────────────────────────────────────
escalation:
  primary_owner: [@github-handle or team]
  secondary_owner: [@github-handle or team]   # paged if primary doesn't respond within SLA

  on_loop_timeout:
    notify: primary_owner
    sla_minutes: 30
    if_unack: escalate to secondary_owner

  on_verifier_fail:
    notify: primary_owner
    sla_minutes: 1440                # 24h — non-urgent, becomes an open item in STATE.md
    if_unack: surfaced in next daily triage as a stale open item

  on_rollback:
    notify: [primary_owner, secondary_owner]   # always both — rollback is the highest-severity event
    sla_minutes: 15
    if_unack: escalate to [team lead / on-call rotation]
    channel: [Slack channel / PagerDuty service / etc.]

  on_l3_category_disabled:           # i.e. auto-merge was turned off for a fix category after rollback
    notify: primary_owner
    requires_manual_reenable: true   # never auto-re-enables, even after cool-down