Files
root 1d027f71f6 feat(contracts): add infrastructure-maintenance contract
New responsibility contract consolidating host-level system maintenance
and Docker image lifecycle management, filling the gap left by
infrastructure-update (which owns cluster-wide apt waves).

Scope:
- OS package updates on primary host with pre-update snapshot/backup check
- Docker image pulls for LiteLLM, SearXNG, and other running containers
- Container restarts with per-stack health verification
- Post-update verification: LiteLLM, SearXNG, Zulip, Gitea, PM2, Hermes gateways
- Rollback on failure (image/apt/config restore) with circuit breaker

Owner: ops (firstmate secondmate). Trigger: weekly Sunday 2am ET.
Escalation: warning/critical->abiba+mumuni, fatal->abiba+mumuni+kwame.
circuit_breaker: max_retries 2, window 7200, trip_action escalate_to_fatal.
depends_on: infrastructure-monitoring (pre-update health baseline).

Registry:
- Add infrastructure-maintenance to by_category.maintenance, by_domain.infrastructure,
  by_owner.ops (new), by_trigger.scheduled, by_sensitivity.high
- Add 'ops' to owners list
- Move infrastructure-update owner abiba -> ops (in contracts entry + by_owner index)

Also adds '## Maintaining this file' section to AGENTS.md per fm-ensure-agents-md.
2026-07-18 22:02:45 +00:00

5.5 KiB

AGENTS.md — Prose Contracts Repo

All agents operating on prose contracts MUST follow this workflow. No exceptions.

The Rule

No agent pushes directly to main. All changes go through PRs with automated validation.

Why

Two incidents taught us this:

  1. The .117→.19 IP fix — A stale IP in a contract was "fixed" without verification, breaking Zulip. The fix was right but the approach was wrong. Automated consistency checks would have caught it.

  2. The /grafana/ route regression — An nginx route that was deliberately removed (Jul 2) was re-added to a contract diagram. CI linting now catches this automatically.

Agent Workflow

┌─────────────────────────────────────────────────────────┐
│  1. Clone repo → create branch → make changes           │
│  2. Push branch → open PR                                │
│  3. CI pipeline runs automatically:                      │
│     ✅ validate: frontmatter (kind, name, description)   │
│     ✅ lint: structure + regression detection            │
│     ✅ ai-review: LiteLLM reviews diff vs ground truth   │
│  4. All green → merge PR to main                         │
│  5. Agents run contracts from main                       │
└─────────────────────────────────────────────────────────┘

Branch Protection (enforced by Gitea)

Rule Enforcement
Direct push to main Blocked (except abiba-bot for emergencies)
PR merge without passing CI Blocked — all 3 checks must be green
Status check contexts pr-pipeline / validate, pr-pipeline / lint, pr-pipeline / ai-review

What the CI checks for

Stage 1 — Validate

  • YAML frontmatter is valid (proper --- delimiters)
  • kind field is one of: function, responsibility, gateway, pattern, test, template
  • name and description fields are present

Stage 2 — Lint

  • Responsibility contracts have ## Maintains
  • Function contracts have ## Parameters and ## Returns
  • Regression rules (automatic rejection):
    • /grafana/ nginx route — was reverted Jul 2, must not reappear
    • CT 122 or CT 123 as CT ID labels — don't exist in the cluster
    • These rules are hardcoded in scripts/prose-lint.sh

Stage 3 — AI Review

  • Diff is sent to syslog-auto model via LiteLLM
  • Review checks against infrastructure-control ground truth:
    • CT IDs match PVE cluster (100-117, no 122/123)
    • Grafana is direct LAN :3001, NOT behind nginx
    • Zulip is CT 117 on storepve (bridge IP .19)
    • Strix Halo :8080 is firewalled to .116 only
  • Review is posted to the PR

Authorization

Who can change what

Contract Sensitivity Who can change
infrastructure-control.prose.md CRITICAL — topology source of truth Abiba only (after live verification)
proxmox-monitor.prose.md CRITICAL — deployed monitoring Abiba only
hermes-config-template.prose.md HIGH — all agent configs Abiba, Mumuni, Tanko
zulip-health.prose.md HIGH — agent communication Abiba, Mumuni
Other contracts Normal Any registered agent
scripts/*.sh HIGH — runtime scripts Abiba only

Enforcement (self-policing)

The CI does not block based on author identity today (Gitea doesn't support CODEOWNERS natively). Instead, agents self-enforce:

  1. Before changing a CRITICAL contract, check with Abiba
  2. If you're unsure, tag @abiba-bot in the PR description
  3. Abiba reviews CRITICAL contract changes before merge

Emergency Bypass

In an emergency (service down, fix must ship immediately):

  1. Push to a branch
  2. Open PR with [EMERGENCY] in the title
  3. CI still runs — but if it fails and the fix is verified, abiba-bot can bypass and push directly to main
  4. Post-incident: open a follow-up PR to fix any CI violations

Quick Start

# Clone
git clone https://git.sysloggh.net/SyslogSolution/prose-contracts.git
cd prose-contracts

# Create branch
git checkout -b fix/my-change

# Make changes, test locally
bash scripts/prose-lint.sh     # run lint locally before pushing

# Push and open PR
git add -A
git commit -m "fix: description of change"
git push origin fix/my-change

# Open PR at https://git.sysloggh.net/SyslogSolution/prose-contracts/pulls
# CI runs automatically — wait for all checks to pass
# Merge when green

Verification Before Acting

Contracts are leads, not facts. Live-state fields (IPs, ports, credentials) drift. Before acting on any value from a contract, verify it against the live system.

Follow the verify-before-mutate protocol:

safe-mutate --verify "CMD" [--expect "PATTERN"] --mutate "CMD" [--reason "WHY"]

Writing New Contracts

Read the Authoring Guide before writing any new contract. It covers the full process: verify → draft → lint → review → ship, with templates and style rules.

Maintaining this file

Keep this file for knowledge useful to almost every future agent session in this project. Do not repeat what the codebase already shows; point to the authoritative file or command instead. Prefer rewriting or pruning existing entries over appending new ones. When updating this file, preserve this bar for all agents and keep entries concise.