Skip to main content

PLATO Deployment Approval Room — deployment gating as an engine block

Project description

PLATO Deployment Approval Room

Deployment gating as a PLATO engine block — the third room in the SuperInstance ecosystem.

Tests

What is this?

A PLATO Room that gates deployments based on CI status, test coverage, security scans, and rate limits. It follows the PLATO architecture:

Concept In this room
Sensors CI status, test coverage delta, security scan results, diff size, deployment count Pull data from GitHub + CI on each tick
Actuators Approve deployment, block deployment, post approval comment, trigger rollback Push decisions back to GitHub
Tick loop Configurable rate (default 0.1 Hz = every 10s) Polls for deployment state changes
Alarms coverage_drop, ci_failing, force_push_main, rate_limit_exceeded Fire on policy violations
Conservation Max deployments per day (rate limiting as conservation law) Deployments are a conserved quantity
History Ring buffer of last 1000 ticks — full audit trail of all decisions Immutable deployment log

The room exposes the standard PLATO wire protocol — any PLATO client can connect, read sensors, check alarms, and trigger actuators.

Quick Start

Standalone (single deployment check)

export GITHUB_TOKEN=ghp_your_token_here
python -m plato_room_deployment_approval.room --repo owner/repo --pr 42 --once

Prints a deployment approval decision and exits.

Long-lived server

export GITHUB_TOKEN=ghp_your_token_here
python -m plato_room_deployment_approval.room --repo owner/repo --watch --port 1236

Then connect with any PLATO client:

from plato_core.protocol import PlatoClient

with PlatoClient.connect("localhost", 1236) as client:
    welcome = client.recv_response()
    print(f"Connected to {welcome.room_id}")

    client.send("tick")
    tick = client.recv_response()
    print(f"Deployment state: {tick.data}")

    client.send("alarm list")
    alarms = client.recv_response()
    for a in alarms.alarms:
        print(f"  {a.id}: {a.state}")

    # Approve deployment
    client.send("actuator approve_deployment 1")

GitHub Action

# .github/workflows/deployment-gate.yml
name: PLATO Deployment Gate
on:
  pull_request:
    types: [opened, synchronize]
  push:
    branches: [main]

jobs:
  gate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: "3.12"
      - run: pip install plato-core plato-room-deployment-approval
      - run: |
          python -m plato_room_deployment_approval.room \
            --repo ${{ github.repository }} \
            --pr ${{ github.event.pull_request.number }} \
            --once
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Deployment Checks

All checks are deterministic — no LLM, no fuzzy logic. Fast and auditable.

Check What it evaluates Outcome
ci_passing All required CI check runs pass BLOCK if failing
coverage_delta Test coverage change vs. base branch BLOCK if drop > threshold
security_scan Security scan results (from audit room) BLOCK if critical findings
diff_size Total lines changed WARN if > 1000, BLOCK if > 5000
force_push_main Force push to main branch BLOCK immediately
rate_limit Max deployments per day BLOCK if exceeded
review_approval Required reviewers approved BLOCK if not approved

Conservation Law: Deployment Rate Limiting

Deployments are treated as a conserved quantity — the room enforces a maximum number of deployments per day (default: 10). This is the room's conservation law in action.

# Configure rate limit
room.set_conservation_limit("daily_deployments", 5)  # Max 5 deploys/day

# The room tracks deployments and blocks when the limit is reached
# This is not a suggestion — it's enforced by the room protocol

Configuration

Configure via plato-deployment.yml in your repo root:

gates:
  ci_passing: enabled
  coverage_delta:
    max_drop_pct: 5.0  # Block if coverage drops by more than 5%
  security_scan: enabled
  diff_size:
    warn_lines: 1000
    block_lines: 5000
  force_push_main: enabled
  rate_limit:
    max_daily: 10
  review_approval:
    required_reviewers: 1

Options: enabled, disabled, warn.

Architecture

                    PLATO Wire Protocol
                    (TCP, JSON lines)
                           │
          ┌────────────────┼────────────────┐
          │                │                │
     tick command     alarm list      actuator cmd
          │                │                │
          ▼                ▼                ▼
    ┌─────────────────────────────────────────────────┐
    │         Deployment Approval Room                │
    │                                                 │
    │  Sensors               Actuators                │
    │  ├─ ci_status          ├─ approve_deployment    │
    │  ├─ coverage_delta     ├─ block_deployment      │
    │  ├─ security_scan      ├─ post_approval         │
    │  ├─ diff_metrics       └─ trigger_rollback      │
    │  ├─ deployment_count   │                        │
    │  └─ review_status      │                        │
    │                                                 │
    │  Alarms                                        │
    │  ├─ coverage_drop (coverage_delta < -5.0)      │
    │  ├─ ci_failing (ci_failed > 0)                 │
    │  ├─ force_push_main (force_push == 1)          │
    │  └─ rate_limit_exceeded (daily_count >= max)   │
    │                                                 │
    │  Conservation                                  │
    │  └─ daily_deployments: max 10/day              │
    │                                                 │
    │  History (1000-tick ring buffer)                │
    │  └─ Full audit trail of all decisions           │
    └─────────────────────────────────────────────────┘
                           │
                    GitHub API
                           │
          ┌────────────────┼────────────────┐
          │                │                │
     Fetch CI status  Fetch coverage   Post approval
     Fetch PR info    Count deploys    Block merge

Conservation Laws

This room demonstrates conservation laws for AI agents — a core SuperInstance principle:

  • Deployment rate is conserved: the room physically cannot exceed max_daily deployments
  • Audit trail is conserved: all decisions are logged immutably in the history buffer
  • Gate compliance is conserved: no deployment can bypass the gate checks

FLUX Policies

POLICY ci_must_pass {
    SENSE  ci_failed
    GUARD   ci_failed > 0
    ALARM   severity=critical
    ACTUATE block_deployment
    EMIT    "CI is failing — deployment blocked"
}

POLICY coverage_no_drop {
    SENSE  coverage_delta
    GUARD   coverage_delta < -5.0
    ALARM   severity=error
    ACTUATE block_deployment
    EMIT    "Coverage dropped below threshold"
}

Testing

pip install -e ".[test]"
pytest tests/ -v

All tests use simulated data — no GitHub API calls needed.

License

MIT — see LICENSE.

Part of

SuperInstance — the PLATO ecosystem.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

plato_room_deployment_approval-0.1.1.tar.gz (27.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

plato_room_deployment_approval-0.1.1-py3-none-any.whl (21.3 kB view details)

Uploaded Python 3

File details

Details for the file plato_room_deployment_approval-0.1.1.tar.gz.

File metadata

File hashes

Hashes for plato_room_deployment_approval-0.1.1.tar.gz
Algorithm Hash digest
SHA256 866ebf820edeb2686cfc3b236ab4d1a2f6fa0dc78a45c135a4e98b7d7457a2ac
MD5 aef778e969c687cae3067488afd54984
BLAKE2b-256 0ccf929cc386cf6b7824c03cc0b8f395fc6fa11db811e7158ef674b3b2b7f37a

See more details on using hashes here.

File details

Details for the file plato_room_deployment_approval-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for plato_room_deployment_approval-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 2b1137d987b28ab5c89366e57dc60f328a99e87475e57209082393ef4417d676
MD5 39cc0b77a651ede770e4a60f008834ab
BLAKE2b-256 338944d1683b1e25e2d30e9787c22a17b7301b3f2563b21cf39b1c64bdbb83c0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page