5.1 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:
-
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.
-
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) kindfield is one of:function,responsibility,gateway,pattern,test,templatenameanddescriptionfields are present
Stage 2 — Lint
- Responsibility contracts have
## Maintains - Function contracts have
## Parametersand## Returns - Regression rules (automatic rejection):
/grafana/nginx route — was reverted Jul 2, must not reappearCT 122orCT 123as 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-automodel 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:
- Before changing a CRITICAL contract, check with Abiba
- If you're unsure, tag
@abiba-botin the PR description - Abiba reviews CRITICAL contract changes before merge
Emergency Bypass
In an emergency (service down, fix must ship immediately):
- Push to a branch
- Open PR with
[EMERGENCY]in the title - CI still runs — but if it fails and the fix is verified, abiba-bot can bypass and push directly to main
- 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.