Migrate all repos into monorepo context folders
Bahn: aisupport, Analyse-O2C-C2S, awesome-bahn-mcp-servers, beam-mcp,
Confluence_Bot, db-planet-mcp-server, O2C-Harness, project-audit,
Projekt-KIQ-HP, teamlandkarte-mcp
Dhive: Jury-Voting
Privat: CV, NoteGraph (NOTE: NoteGraph needs complete redo after consolidation)
Shared: AI-Orchestrator, OrgMyLife, power_skills_and_more
Shared/references: symphony (read-only)
Bahn repos remain available as independent remotes - this monorepo
pulls them in via subtree, the originals are untouched.
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
# SPEC.md — AI-Orchestrator
|
||||
|
||||
## Purpose
|
||||
|
||||
A Python service implementing the Symphony specification — it polls a task board (OrgMyLife) for agent-ready tasks, dispatches them to a coding agent (Codex CLI or alternative), manages isolated workspaces, and reports results back. Teams manage work; the orchestrator handles execution.
|
||||
|
||||
## Tech Stack
|
||||
|
||||
| Layer | Technology |
|
||||
|-------|-----------|
|
||||
| Language | Python 3.11+ (strict typing) |
|
||||
| Package manager | Hatch (pyproject.toml) |
|
||||
| Testing | pytest + pytest-asyncio + hypothesis (property-based) |
|
||||
| Linting | ruff |
|
||||
| Type checking | mypy (strict) |
|
||||
| HTTP | httpx (client), starlette + uvicorn (server) |
|
||||
| Templating | Jinja2 |
|
||||
| Config format | YAML (WORKFLOW.md with front matter) |
|
||||
| Deployment | Docker / systemd |
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
src/ai_orchestrator/
|
||||
├── cli.py # Entry point (ai-orchestrator command)
|
||||
├── config.py # Typed config from WORKFLOW.md front matter
|
||||
├── workflow.py # WORKFLOW.md parser (YAML + Jinja2 template)
|
||||
├── models.py # Data models (Issue, WorkspaceState, etc.)
|
||||
├── orchestrator.py # Poll loop, dispatch, concurrency, retries
|
||||
├── tracker.py # Abstract tracker interface
|
||||
├── tracker_orgmylife.py # OrgMyLife adapter (REST API)
|
||||
├── workspace.py # Per-issue workspace lifecycle and hooks
|
||||
├── agent_runner.py # Codex subprocess integration
|
||||
├── prompt.py # Jinja2 prompt rendering
|
||||
├── http_server.py # Optional REST API + dashboard
|
||||
└── watcher.py # File system watcher for hot-reload
|
||||
|
||||
scripts/pat_manager/ # PAT lifecycle management (check, alert, rotate)
|
||||
├── checker.py # Token expiry checking
|
||||
├── alerter.py # Alert dispatch (OrgMyLife task creation)
|
||||
├── rotator.py # Token rotation logic
|
||||
├── reporter.py # Status reporting
|
||||
├── registry.py # pat-registry.json I/O
|
||||
├── models.py # PAT data models
|
||||
└── errors.py # Error types
|
||||
```
|
||||
|
||||
## Components
|
||||
|
||||
### Orchestrator Core
|
||||
- **Workflow Loader** — Parses `WORKFLOW.md` (YAML front matter + Jinja2 prompt template)
|
||||
- **Config Layer** — Typed getters, defaults, env var resolution (`$VAR_NAME`), validation
|
||||
- **Tracker Client** — OrgMyLife REST adapter with pagination and state mapping
|
||||
- **Orchestrator** — Poll loop, task dispatch, concurrency limits, retry with backoff
|
||||
- **Workspace Manager** — Per-issue workspace creation, hooks, cleanup
|
||||
- **Agent Runner** — Codex app-server subprocess integration
|
||||
- **HTTP Server** — REST API (`/api/v1/state`) and dashboard for observability
|
||||
|
||||
### PAT Manager
|
||||
- **Checker** — Reads pat-registry.json, calculates days until expiry
|
||||
- **Alerter** — Creates OrgMyLife tasks for expiring/expired tokens, deduplicates
|
||||
- **Rotator** — Automated token rotation (where supported)
|
||||
- **Reporter** — Generates status reports
|
||||
|
||||
## Configuration
|
||||
|
||||
The orchestrator reads `WORKFLOW.md` in the working directory. Format:
|
||||
|
||||
```yaml
|
||||
---
|
||||
tracker:
|
||||
kind: orgmylife
|
||||
endpoint: https://api.andreknie.de
|
||||
api_key: $ORGMYLIFE_API_SECRET
|
||||
polling:
|
||||
interval_ms: 30000
|
||||
workspace:
|
||||
root: ~/ai_orchestrator_workspaces
|
||||
agent:
|
||||
max_concurrent_agents: 3
|
||||
max_turns: 15
|
||||
codex:
|
||||
command: codex app-server
|
||||
approval_policy: auto-edit
|
||||
---
|
||||
|
||||
<Jinja2 prompt template>
|
||||
```
|
||||
|
||||
## Conventions
|
||||
|
||||
- All source in `src/ai_orchestrator/` (installed as package)
|
||||
- Tests in `tests/` — mirror source structure with `test_` prefix
|
||||
- Property-based tests use `_properties` suffix (e.g., `test_alerter_properties.py`)
|
||||
- PAT manager scripts in `scripts/pat_manager/` (standalone, own requirements.txt)
|
||||
- File naming: snake_case for Python modules
|
||||
- Config via environment variables (prefixed as needed) or WORKFLOW.md
|
||||
|
||||
## Rules
|
||||
|
||||
1. Never store secrets in code — use env vars or `.secrets` file.
|
||||
2. All tracker interactions go through the abstract `Tracker` interface.
|
||||
3. Property-based tests (hypothesis) for all domain logic.
|
||||
4. Async by default for I/O operations.
|
||||
5. Typed models for all data transfer (no raw dicts at boundaries).
|
||||
6. PAT manager must deduplicate alerts (check existing tasks before creating new ones).
|
||||
|
||||
## Current State
|
||||
|
||||
- Orchestrator core: implemented (poll, dispatch, workspace, agent runner)
|
||||
- OrgMyLife tracker adapter: implemented
|
||||
- PAT manager: fully implemented + tested (checker, alerter, rotator, reporter)
|
||||
- HTTP server: implemented
|
||||
- Deployment: Docker + docker-compose ready, systemd pending
|
||||
- Blocked: needs Codex CLI or alternative agent installed on target server
|
||||
Reference in New Issue
Block a user