# 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 ` → 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.*