# service
`src/features/service/api.rs`
Minimal Sprint 4 service-candidate surface for the single-node operator path.
This module is intentionally narrow. It does not provide a full production server stack. It exposes:
- service config validation against the shared service candidate profile
- a small blocking TCP/HTTP surface for health, metrics, one query path, and operator routes
- optional bearer-token gating for admin endpoints
---
## Config
```rust
pub struct ServiceConfig {
pub listen_address: String,
pub data_dir: PathBuf,
pub telemetry_endpoint: String,
pub tls_mode: ServiceTlsMode,
pub admin_token: Option<String>,
pub max_requests: usize,
}
```
```rust
pub enum ServiceTlsMode {
Disabled,
OperatorOptional,
}
```
`ServiceConfig::validate()` checks the config against the shared single-node service candidate profile and returns:
```rust
pub struct ServiceValidationReport {
pub profile_id: &'static str,
pub compatible: bool,
pub missing_env: Vec<&'static str>,
pub missing_verbs: Vec<&'static str>,
pub missing_evidence_artifacts: Vec<&'static str>,
pub warnings: Vec<String>,
}
```
Warnings are used for weak but allowed operator settings such as:
- `tls_mode=disabled`
- no `admin_token`
- `max_requests=0` for an unbounded local serve loop
---
## Endpoints
`serve(&ServiceConfig)` binds a blocking stdlib `TcpListener` and serves:
- `GET /livez`
- `GET /readyz`
- `GET /metrics`
- `GET /v1/query?q=...`
- `GET /admin/status`
- `GET /admin/lifecycle?action=status|stop`
When `admin_token` is set, admin endpoints require:
```text
Authorization: Bearer <token>
```
---
## CLI
The service surface is exposed from `src/bin/ir/` through:
- `ir service-report`
- `ir service-validate`
- `ir service-serve`
The product repo also emits operator-facing artifacts with:
```sh
python3 scripts/service_candidate_report.py --report-dir artifacts
python3 scripts/service_lifecycle_report.py --report-dir artifacts
python3 scripts/service_compatibility_report.py --report-dir artifacts
```
This writes:
- `artifacts/service_candidate_report.json`
- `artifacts/service_candidate_report.md`
- `artifacts/service_lifecycle_report.json`
- `artifacts/service_lifecycle_report.md`
- `artifacts/service_compatibility_report.json`
- `artifacts/service_compatibility_report.md`
For a concrete operator flow, see [`../service_single_node.md`](../service_single_node.md).
For the Sprint 5 install/package flow, see [`../service_install.md`](../service_install.md).
`service_compatibility_report.py` packages the Sprint 5 external-facing service proof by combining:
- `service-report`
- `service-validate`
- the service lifecycle evidence artifacts
- a service-backed retrieval-quality report using the same canonical deterministic fixture
This is the product-owned compatibility/evidence handoff for external-facing Phase 2 evaluation.
`service_lifecycle_report.py` seeds a deterministic local fixture, starts the service candidate path, checks:
- `GET /livez`
- `GET /readyz`
- `GET /metrics`
- `GET /v1/query?q=...`
- `GET /admin/status`
- `GET /admin/lifecycle?action=stop`
and then emits an operator-facing lifecycle/status evidence pair from that real service run.
---
## Limits
- TLS is config-shaped only in Sprint 4. No transport encryption is implemented yet.
- Auth is limited to optional bearer-token gating for admin routes.
- The service is single-process and blocking; it is a service candidate surface, not a hardened runtime.