DraftLint Railway Validator¶
Status: Active Railway integration fork Service name:
DraftLint Fork with Local AILast verified: 2026-07-16
Source And Runtime Identity¶
- Variant ID:
draftlint-railway-validator - Canonical local repository:
/Users/adeelyj/code/local ai server setup/Draftlint-forked-railway-adapter - Remote repository: adeelyj/Draftlint-forked-railway-adapter
- Upstream: sreekarrs/DraftLint
- Active branch:
railway-adapter - GitHub default branch:
main - Verified commit:
a0f3f1092b598be3be65a555a7b41b4189cf8e3b - Runtime: Railway project
Testing Service, environmentproduction - Public service: draftlint-fork-with-local-ai-production.up.railway.app
- Not to be confused with: DraftLint Detector Gateway, which only serves detector predictions
What The Fork Changes¶
The adapter preserves the upstream validation pipeline while replacing deployment-specific connections:
- local YOLO can be replaced by the authenticated IONOS detector gateway,
- Azure/GitHub Models can be replaced by an OpenAI-compatible LiteLLM endpoint,
- Railway-compatible dependencies and Docker setup are included,
- uploads receive unique names and are cleaned after jobs,
- a browser smoke-test page and API documentation are exposed,
- synchronous and background workflow-trace views expose intermediate results,
- detector discovery can select the specialist ensemble automatically.
The fork is 10 commits ahead of the verified upstream snapshot. Most adapter changes are concentrated in api/app.py, src/config.py, src/main.py, src/processors/inference_runner.py, src/validators/langchain_validator.py, dependencies, and Docker files.
Full Validation Workflow¶
| Step | What happens | Main code | Where | Intermediate result |
|---|---|---|---|---|
| 0 | Accept upload and initialize validator | api/app.py |
Railway | Job ID, filename, standard, startup status |
| 1 | Load PDF/image, rasterize, and resize | src/processors/document_processor.py |
Railway container | Image shape and maximum dimension |
| 2 | Preprocess for OCR and detection | src/processors/document_processor.py |
Railway container | Enhanced/binary debug images |
| 3 | Run YOLO symbol/layout inference | src/processors/inference_runner.py |
IONOS gateway in deployed mode | Provider, detector IDs, call status, counts by group |
| 4 | Parse FCF/GD&T compartments | src/processors/fcf_parser.py |
Railway container | FCF count and parse warnings |
| 5 | Link dimensions and annotations to drawing views | link_views_advanced.py |
Railway container | Assignment/view counts and linked image |
| 6 | OCR title block and notes | src/processors/ocr_engine.py |
Railway container | OCR backend, text counts, short previews |
| 7 | Validate selected regions with an LLM | src/validators/langchain_validator.py |
External LiteLLM/local-AI route when enabled | Provider, model name, result categories |
| 8 | Assemble standards issues | src/main.py, src/validators/standards_rules.py |
Railway container | Critical/major/minor counts |
| 9 | Generate report and artifacts | src/utils/report_generator.py |
Railway filesystem | Report files, annotated images, inspection output |
API Surface¶
| Endpoint | Purpose | Response |
|---|---|---|
GET / |
Browser smoke test and upload form | HTML |
GET /api/health |
Service health | JSON |
GET /docs |
FastAPI/OpenAPI documentation | HTML |
POST /api/validate |
Full validation | Final validation JSON |
POST /api/validate/trace |
Full validation with a synchronous trace | HTML workflow table |
POST /api/validate/trace/jobs |
Start a background trace job | Live polling HTML |
GET /api/validate/trace/jobs/{job_id} |
Poll trace state | JSON |
GET /api/validate/trace/jobs/{job_id}/result |
Open completed trace | HTML |
GET /api/results/{filename} |
Retrieve a generated result artifact | File |
GET /api/debug/{filename} |
Retrieve a debug preprocessing artifact | File |
Trace jobs are stored in process memory. A restart loses job state. The service had no Railway volume attached when verified, so result/debug files are also not durable deployment records.
External Connections¶
Detector provider¶
In deployed gateway mode, InferenceRunner does not load local YOLO weights. It:
- obtains detector IDs from configuration or
GET /models, - sends a base64-encoded PNG to
POST /predict/{detector_id}, - maps returned labels into five internal groups,
- records each call in the workflow trace.
The live service uses the IONOS DraftLint Detector Gateway. The preferred detector is 26, the YOLO26l specialist ensemble.
LLM provider¶
The fork supports azure, github, openai, litellm, and disabled. For the local-AI route, LiteLLM presents an OpenAI-compatible API and the service reads the RapidDraft text-agent base URL, API key, and model name.
AI validation is skipped when credentials or the required endpoint are unavailable. The remaining local rules pipeline can continue, but a “compliant” report with zero issues must not be interpreted as proof that all AI checks ran.
The last documented local-AI limitation was a coder model rejecting image input. Use a multimodal model/mmproj route for image-bearing validation, or deliberately limit the LLM stage to text-compatible requests.
Configuration Contract¶
Important variable names, without values:
| Group | Variables |
|---|---|
| Pipeline | DRAFTLINT_PIPELINE_MODE, DETECTOR_PROVIDER, STANDARD |
| Gateway | DRAFTLINT_DETECTOR_GATEWAY_URL, DRAFTLINT_DETECTOR_GATEWAY_TOKEN, DRAFTLINT_DETECTOR_GATEWAY_DETECTOR_IDS, DRAFTLINT_DETECTOR_GATEWAY_TIMEOUT_SECONDS, DRAFTLINT_DETECTOR_THRESHOLD |
| LLM | LLM_PROVIDER, RAPIDDRAFT_AGENT_TEXT_BASE_URL, RAPIDDRAFT_AGENT_TEXT_API_KEY, RAPIDDRAFT_AGENT_TEXT_MODEL, RAPIDDRAFT_AGENT_TEXT_TIMEOUT_SECONDS |
| Storage | UPLOAD_DIR, RESULTS_DIR, TEMP_DIR, DEBUG_OUTPUT_DIR |
| Runtime | PORT, LOG_LEVEL |
Do not publish values for token or API-key variables.
Failure Interpretation¶
| Symptom | Likely meaning |
|---|---|
| Gateway call warning but trace continues | One or more detectors failed; inspect gateway_calls and detection counts |
LLM step is skipped |
LLM disabled or required configuration missing |
| LLM step reports no useful results | Model may not support images or structured output |
| Trace job disappears | Railway process restarted; jobs are in memory |
| Artifact returns 404 later | Ephemeral filesystem or restart removed it |
| Final report says compliant with empty AI analysis | Pipeline completed, but this alone does not prove detector/OCR/LLM quality |
Open Questions¶
- Should trace state and artifacts move to durable storage before wider use?
- Should the Railway service require application authentication instead of exposing its upload form publicly?
- Which multimodal local-AI model should be the validated default?
- Should
railway-adapterbecome the remote default branch?
Sources¶
- Railway adapter branch
- Local code review of
api/app.py,src/main.py,src/config.py, andsrc/processors/inference_runner.py - Railway CLI deployment and variable-name metadata verified 2026-07-16
- Live
GET /api/healthverified 2026-07-16 - DraftLint System Family