Files

88 lines
2.8 KiB
Markdown
Raw Permalink Normal View History

# Operator Ingress Gate
Transport-agnostic, idempotent write gate for all operator-originated Gitea mutations.
## Purpose
This is the **single canonical write path** for any external command that creates, updates, or merges Gitea issues/PRs. Whether the command arrives via Nostr DM, Matrix, Telegram, or a local script, it must pass through this gate.
## Design Invariants
1. **Deterministic idempotency key** — SHA-256 of `(source, action, repo, sorted_payload)`.
2. **Local ledger deduplication** — First line of defense; replayed commands return the original ACK instantly.
3. **Gitea-side probing** — Second line of defense; scans existing issues/comments for duplicates before mutating.
4. **Proof-of-execution** — Every mutation embeds the gate-key in the Gitea comment/issue body, creating an audit trail.
5. **Replay safety** — Running the same command twice never double-writes.
## Structure
```
operator-gate/
├── gitea_gate.py # Core gate logic (Command, Ack, GiteaGate)
├── adapters/
│ └── nostur_adapter.py # Nostr DM adapter
├── tests/
│ └── test_gate_idempotency.py
└── README.md # This file
```
## Supported Actions
| Action | Payload keys |
|---------------|-------------------------------------------|
| `create_issue`| `title`, `body`, `assignees[]`, `labels[]`|
| `add_comment` | `issue_num`, `body` |
| `close_issue` | `issue_num` |
| `assign_issue`| `issue_num`, `assignees[]` |
| `merge_pr` | `pr_num` |
## Usage
```python
from gitea_gate import create_issue, add_comment
ack = create_issue(
source="nostr:npub10trqk...",
repo="Timmy_Foundation/timmy-home",
title="Fix relay timeout",
body="The nostr relay drops connections after 30s.",
assignees=["allegro"],
)
print(ack.gitea_url) # Canonical URL of the created issue
print(ack.idempotency_key) # 32-char fingerprint
```
## Nostur Adapter
The Nostur adapter polls the local Nostr relay (`ws://localhost:2929`) for Kind-4 DMs from authorized operator pubkeys. It normalizes DM text into gate commands:
- `status` → queue summary for `the-nexus`
- `create <repo> <title>` → create issue
- `comment <repo> #<num> <text>` → add comment
- `close <repo> #<num>` → close issue
- `assign <repo> #<num> <user1,user2>` → assign issue
- `merge <repo> #<num>` → merge PR
Run it:
```bash
python3 operator-gate/adapters/nostur_adapter.py
```
## Running Tests
```bash
cd operator-gate
python3 -m unittest tests.test_gate_idempotency -v
```
## Future Adapters
- Matrix bot adapter
- Telegram bot adapter
- Local CLI adapter (`hermes operator-do ...`)
---
*Built for the Timmy Foundation fleet. Sovereignty and service always.*