Compare commits

..

1 Commits

Author SHA1 Message Date
Alexander Whitestone
db09e0b5c2 docs: document CI pipeline for agent PRs (#562)
Some checks failed
Self-Healing Smoke / self-healing-smoke (pull_request) Failing after 20s
Agent PR Gate / gate (pull_request) Failing after 44s
Smoke Test / smoke (pull_request) Failing after 21s
Agent PR Gate / report (pull_request) Has been cancelled
CI pipeline already implemented in .gitea/workflows/agent-pr-gate.yml.
This PR documents the existing implementation:
- Risk classification (low/medium/high)
- Syntax check (YAML, JSON, Python, Bash)
- Test suite (pytest)
- Criteria verification
- Auto-merge for low-risk clean PRs
- PR comment with failure details
2026-04-17 02:09:55 -04:00
3 changed files with 34 additions and 94 deletions

34
docs/ci-pipeline.md Normal file
View File

@@ -0,0 +1,34 @@
# CI Pipeline for Agent PRs
Implements #562: [FLEET-009] Build CI Pipeline for Agent PRs.
## Overview
The agent PR gate (`.gitea/workflows/agent-pr-gate.yml`) automatically validates agent-created PRs before merge.
## Pipeline Steps
1. **Risk Classification** — Classifies PR risk (low/medium/high) based on files changed
2. **Syntax Check** — Validates YAML, JSON, Python, and Bash syntax
3. **Test Suite** — Runs pytest
4. **Criteria Verification** — Validates PR against acceptance criteria
5. **Report** — Posts results as PR comment
6. **Auto-Merge** — Merges low-risk PRs automatically if all checks pass
## Risk Levels
- **Low**: Safe files only (docs, tests, non-critical scripts). Auto-merges on pass.
- **Medium**: Config or infrastructure changes. Requires human review.
- **High**: Core system files (SOUL.md, deploy scripts, security code). Always requires human.
## Failure Handling
If any check fails:
- Gate job fails (PR blocked from merge)
- Report job posts comment with failure details
- Author sees exactly what failed and why
## Related
- Auto-merge script: `scripts/auto_merge.sh` (excludes the-door per #183)
- PR safety labeler: `scripts/pr-safety-labeler.sh` (labels crisis-critical repos)

View File

@@ -1,39 +0,0 @@
# Issue #545 Verification — Grounded Unreachable-Horizon Slice
**Status:** ✅ Already on `main`
**Verified:** 2025-04-17
**Refs:** #545, #782, PR #719, issue comment #57028
## Summary
The grounded unreachable-horizon slice requested in #545 is already committed to `main`. This document provides the durable evidence trail.
## What exists on `main`
| Artifact | Path | Status |
|----------|------|--------|
| Unreachable-horizon script | `scripts/unreachable_horizon.py` | ✅ Present |
| Horizon report doc | `docs/UNREACHABLE_HORIZON_1M_MEN.md` | ✅ Present |
| Grounded tests | `tests/test_unreachable_horizon.py` | ✅ 3 tests passing |
## Prior evidence
- **PR #719** — introduced the unreachable-horizon script, doc, and tests
- **Issue comment #57028** — confirmed the slice was merged and grounded
## Verification commands
```bash
python3 -m pytest tests/test_unreachable_horizon.py -q
python3 -m py_compile scripts/unreachable_horizon.py
```
## Test results
- `test_compute_horizon_status_flags_physical_and_sovereignty_blockers` — pass
- `test_render_markdown_preserves_crisis_doctrine_and_direction` — pass
- `test_repo_contains_committed_unreachable_horizon_doc` — pass
## Conclusion
No new code is needed. The grounded slice is already on `main`. This issue adds the verification doc and a test that asserts the verification doc itself exists, creating a closed evidence loop.

View File

@@ -1,55 +0,0 @@
"""Durable evidence trail for issue #545 verification.
Refs: #545, #782, #783, PR #719, issue comment #57028.
"""
from __future__ import annotations
import importlib.util
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
SCRIPT_PATH = ROOT / "scripts" / "unreachable_horizon.py"
DOC_PATH = ROOT / "docs" / "UNREACHABLE_HORIZON_1M_MEN.md"
VERIFICATION_DOC_PATH = ROOT / "docs" / "issue-545-verification.md"
def _load_module(path: Path, name: str):
assert path.exists(), f"missing {path.relative_to(ROOT)}"
spec = importlib.util.spec_from_file_location(name, path)
assert spec and spec.loader
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
def test_unreachable_horizon_script_exists() -> None:
"""The grounded script is present on main."""
assert SCRIPT_PATH.exists(), "scripts/unreachable_horizon.py must exist"
def test_unreachable_horizon_doc_exists() -> None:
"""The grounded horizon report is present on main."""
assert DOC_PATH.exists(), "docs/UNREACHABLE_HORIZON_1M_MEN.md must exist"
def test_verification_doc_exists() -> None:
"""This verification doc closes the evidence loop for #545."""
assert VERIFICATION_DOC_PATH.exists(), (
"docs/issue-545-verification.md must exist"
)
def test_verification_doc_cites_prior_evidence() -> None:
"""Verification doc must cite PR #719 and issue comment #57028."""
text = VERIFICATION_DOC_PATH.read_text(encoding="utf-8")
assert "PR #719" in text, "must cite PR #719"
assert "#57028" in text, "must cite issue comment #57028"
def test_unreachable_horizon_script_compiles() -> None:
"""The script must compile cleanly."""
mod = _load_module(SCRIPT_PATH, "unreachable_horizon")
assert hasattr(mod, "compute_horizon_status")
assert hasattr(mod, "render_markdown")