Three workstreams implemented: W1 (Repo Split): Remove proprietary BloxServer files and docs, update pyproject.toml URLs to public GitHub, clean doc references, add CI workflow (.github/workflows/ci.yml) and CONTRIBUTING.md. W2 (Message Journal): Add DispatchHook protocol for dispatch lifecycle events, SQLite-backed MessageJournal with WAL mode for certified-mail delivery guarantees (PENDING→DISPATCHED→ACKED/FAILED), integrate hooks into StreamPump._dispatch_to_handlers(), add journal REST endpoints, and aiosqlite dependency. W3 (Hot Deployment): Add RestartOrchestrator for graceful restart with queue drain and journal stats collection, SIGHUP signal handler in CLI, POST /organism/restart endpoint, restart-aware app lifespan with journal recovery on boot, and os.execv/subprocess re-exec for Unix/Windows. All 439 tests pass (37 new tests for W2/W3). Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
74 lines
2.1 KiB
Markdown
74 lines
2.1 KiB
Markdown
# Contributing to xml-pipeline
|
|
|
|
Thank you for considering contributing to xml-pipeline.
|
|
|
|
## Development Setup
|
|
|
|
```bash
|
|
git clone https://github.com/xml-pipeline/xml-pipeline.git
|
|
cd xml-pipeline
|
|
python -m venv .venv
|
|
source .venv/bin/activate # Linux/macOS
|
|
# .venv\Scripts\activate # Windows
|
|
|
|
pip install -e ".[dev]"
|
|
```
|
|
|
|
## Running Tests
|
|
|
|
```bash
|
|
pytest tests/ -v
|
|
```
|
|
|
|
Skip slow/integration tests:
|
|
|
|
```bash
|
|
pytest tests/ -v -m "not slow"
|
|
```
|
|
|
|
## Code Style
|
|
|
|
This project uses **ruff** for linting and formatting, **mypy** for type checking.
|
|
|
|
```bash
|
|
ruff check xml_pipeline/ tests/
|
|
ruff format xml_pipeline/ tests/
|
|
mypy xml_pipeline/
|
|
```
|
|
|
|
All functions must have type hints. Async handlers use `async def`.
|
|
|
|
## Pull Request Process
|
|
|
|
1. Fork the repo and create a feature branch from `main`.
|
|
2. Write tests for new functionality in `tests/`.
|
|
3. Ensure `pytest`, `ruff check`, and `mypy` pass.
|
|
4. Keep commits focused and write clear commit messages.
|
|
5. Open a PR against `main` with a description of what changed and why.
|
|
|
|
## Architecture
|
|
|
|
Read `CLAUDE.md` for the full architecture overview. Key principles:
|
|
|
|
- **XML is the sovereign wire format** -- all messages are validated XML envelopes.
|
|
- **Handlers are untrusted** -- the pump enforces identity, routing, and thread isolation.
|
|
- **Pipeline steps are composable** -- add new processing stages by inserting async functions.
|
|
- **Async-first** -- everything is `async def`, powered by aiostream.
|
|
|
|
## Adding a New Pipeline Step
|
|
|
|
1. Create `xml_pipeline/message_bus/steps/your_step.py`.
|
|
2. Implement `async def your_step(state: MessageState) -> MessageState`.
|
|
3. Insert into the pipeline in `stream_pump.py` `build_pipeline()`.
|
|
4. Add tests in `tests/test_pipeline_steps.py`.
|
|
|
|
## Adding a New Handler
|
|
|
|
1. Define a `@xmlify @dataclass` payload in your handler module.
|
|
2. Write an `async def handle_*(payload, metadata) -> HandlerResponse | None`.
|
|
3. Register in `organism.yaml` under `listeners`.
|
|
4. See `docs/handler-contract-v2.1.md` for the full contract.
|
|
|
|
## License
|
|
|
|
By contributing, you agree that your contributions will be licensed under the MIT License.
|