Skip to content

feat: add deterministic receipt-based promotion gate - #37

Merged
divo12 merged 3 commits into
freshfrom
stack/v2-03-gate-v2
Sep 4, 2026
Merged

feat: add deterministic receipt-based promotion gate#37
divo12 merged 3 commits into
freshfrom
stack/v2-03-gate-v2

Conversation

@divo12

@divo12 divo12 commented Sep 3, 2026

Copy link
Copy Markdown
Owner

Summary

  • add pure decide_promotion(policy, accepted_run, candidate_run) over PR2 EvaluatedRunReceipt
  • validate self-hashes, accepted/candidate sides, policy and controls digests, distinct Git commit/tree identities, exact ordered task partitions, verifier identities, receipt IDs, and normalized scores
  • compare authoritative pass sets with strict improvement and no regression
  • enforce explicit cost/latency presence and inclusive candidate limits; missing evidence is inconclusive and exceeded limits reject
  • return immutable typed status/reasons with canonical stdlib JSON + SHA-256 decision IDs

Scope

Pure gate only: no Git, Harbor, Langfuse, filesystem, MCP, clock, randomness, runtime, registry, factory, or dependency changes. This PR is a fresh replacement for the paused observation-based PR36 and targets stack/v2-02-candidate only.

Verification

  • uv run ruff check src tests plugins/openflywheel/scripts/mcp_server.py — clean
  • uv run mypy src tests plugins/openflywheel/scripts/mcp_server.py — clean
  • uv run pytest --cov=ofw --cov-report=term-missing --cov-fail-under=90 -q — 340 passed, 2 skipped, 95.27%
  • uvx --from radon radon cc -s -a ... — changed production functions CC <= 5
  • gate-focused coverage — 100% statement/branch
  • all four skill validators and plugin validation — passed

Do not merge before PR2 remains accepted and reviewed.


Summary by cubic

Adds a pure, deterministic promotion gate that decides whether a candidate run should replace the accepted run based on evaluated run receipts.

Gate behavior

  • Validates receipt self-hashes, policy and controls digests, run sides, distinct Git identities, exact ordered task partitions, verifier identities, and score integrity; metrics must be finite and within configured bounds.
  • Error, abstain, unsupported, and unverified outcomes are inconclusive.
  • Accepts only on strict pass-set improvement; any pass regression or no improvement rejects.
  • Missing cost or latency evidence is inconclusive; candidate limit violations reject and take precedence over missing evidence.
  • Returns immutable typed decisions with canonical JSON and SHA-256 decision IDs.
  • The gate is self-contained with no Git, filesystem, network, or runtime dependencies.

Written for commit 4ba81a4. Summary will update on new commits.

Review in cubic

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 3 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread src/ofw/evolution/gate.py
Comment thread src/ofw/evolution/gate.py Outdated
Comment thread src/ofw/evolution/gate.py Outdated
@divo12
divo12 force-pushed the stack/v2-03-gate-v2 branch from bd36934 to 4ba81a4 Compare September 4, 2026 05:34
@divo12
divo12 changed the base branch from stack/v2-02-candidate to fresh September 4, 2026 05:34
@divo12
divo12 merged commit 4031c37 into fresh Sep 4, 2026
1 check passed
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