Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
296 changes: 187 additions & 109 deletions CHANGELOG.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ where things live, and the commands and rules that matter.

Before making design decisions or judgment calls, read
[`docs/VISION_AND_GOALS.md`](docs/VISION_AND_GOALS.md): what OpenProcessor is
for, the v0.4.1 feature scope, and the standards the code is held to (no dead
for, the v0.5.0 feature scope, and the standards the code is held to (no dead
code, no compatibility shims, fail-closed isolation, class identity by name
never index, review depth matched to real risk).

Expand Down
3 changes: 1 addition & 2 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,7 @@ computer.
### Release checksums are integrity, not authenticity

The installer checks every downloaded file against the release's
`SHA256SUMS`, pins images by digest from `images.lock`, pins Cropwright's
files through `cropwright.lock`, and cross-checks each `images.lock` entry's
`SHA256SUMS`, pins images (Cropwright's included) by digest from `images.lock`, and cross-checks each `images.lock` entry's
image repo against `scripts/lib/image_keys.sh`. These catch truncated or
corrupted downloads and an internally inconsistent release. They do **not**
prove who published the release: `SHA256SUMS` comes from the same origin as
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.4.1
0.5.0
20 changes: 10 additions & 10 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ x-gateway-wrap: &gateway_wrap |

services:
triton-server:
image: ${OP_TRITON_IMAGE:-${OP_IMAGE_REPO:-davidamacey}/openprocessor-triton:${OP_IMAGE_TAG:-0.4.1}}
image: ${OP_TRITON_IMAGE:-${OP_IMAGE_REPO:-davidamacey}/openprocessor-triton:${OP_IMAGE_TAG:-0.5.0}}
container_name: ${COMPOSE_PROJECT_NAME:-openprocessor}-triton
logging: *default-logging
restart: always
Expand Down Expand Up @@ -132,7 +132,7 @@ services:
- triton_net

api:
image: ${OP_API_IMAGE:-${OP_IMAGE_REPO:-davidamacey}/openprocessor:${OP_IMAGE_TAG:-0.4.1}}
image: ${OP_API_IMAGE:-${OP_IMAGE_REPO:-davidamacey}/openprocessor:${OP_IMAGE_TAG:-0.5.0}}
container_name: ${COMPOSE_PROJECT_NAME:-openprocessor}-api
logging: *default-logging
restart: always
Expand Down Expand Up @@ -315,7 +315,7 @@ services:
cropwright:
profiles: ['cropwright']
# CROPWRIGHT_IMAGE (a full reference, e.g. a digest pin) wins over CROPWRIGHT_TAG.
image: ${CROPWRIGHT_IMAGE:-${OP_IMAGE_REPO:-davidamacey}/cropwright:${OP_IMAGE_TAG:-0.4.1}}
image: ${CROPWRIGHT_IMAGE:-${OP_IMAGE_REPO:-davidamacey}/cropwright:${OP_IMAGE_TAG:-0.5.0}}
container_name: ${COMPOSE_PROJECT_NAME:-openprocessor}-cropwright
# Soft scheduling floor for the static-file nginx, not a cap.
mem_reservation: 64m
Expand Down Expand Up @@ -376,7 +376,7 @@ services:
# ===================================================================

curation-detection-worker:
image: ${OP_API_IMAGE:-${OP_IMAGE_REPO:-davidamacey}/openprocessor:${OP_IMAGE_TAG:-0.4.1}}
image: ${OP_API_IMAGE:-${OP_IMAGE_REPO:-davidamacey}/openprocessor:${OP_IMAGE_TAG:-0.5.0}}
container_name: ${COMPOSE_PROJECT_NAME:-openprocessor}-detection-worker
logging: *default-logging
mem_reservation: 1g
Expand Down Expand Up @@ -442,7 +442,7 @@ services:
- triton_net

curation-vlm-worker:
image: ${OP_API_IMAGE:-${OP_IMAGE_REPO:-davidamacey}/openprocessor:${OP_IMAGE_TAG:-0.4.1}}
image: ${OP_API_IMAGE:-${OP_IMAGE_REPO:-davidamacey}/openprocessor:${OP_IMAGE_TAG:-0.5.0}}
container_name: ${COMPOSE_PROJECT_NAME:-openprocessor}-vlm-worker
logging: *default-logging
mem_reservation: 512m
Expand Down Expand Up @@ -481,7 +481,7 @@ services:
- triton_net

curation-auto-label-worker:
image: ${OP_API_IMAGE:-${OP_IMAGE_REPO:-davidamacey}/openprocessor:${OP_IMAGE_TAG:-0.4.1}}
image: ${OP_API_IMAGE:-${OP_IMAGE_REPO:-davidamacey}/openprocessor:${OP_IMAGE_TAG:-0.5.0}}
container_name: ${COMPOSE_PROJECT_NAME:-openprocessor}-auto-label-worker
logging: *default-logging
mem_reservation: 2g
Expand Down Expand Up @@ -545,7 +545,7 @@ services:
- triton_net

curation-cluster-refresh:
image: ${OP_API_IMAGE:-${OP_IMAGE_REPO:-davidamacey}/openprocessor:${OP_IMAGE_TAG:-0.4.1}}
image: ${OP_API_IMAGE:-${OP_IMAGE_REPO:-davidamacey}/openprocessor:${OP_IMAGE_TAG:-0.5.0}}
container_name: ${COMPOSE_PROJECT_NAME:-openprocessor}-cluster-refresh
logging: *default-logging
mem_reservation: 1g
Expand Down Expand Up @@ -581,7 +581,7 @@ services:
# On-demand only (no `restart:` — see docker/evaluator/Dockerfile):
# `docker compose --profile curation run --rm curation-evaluator`.
curation-evaluator:
image: ${OP_EVALUATOR_IMAGE:-${OP_IMAGE_REPO:-davidamacey}/openprocessor-evaluator:${OP_IMAGE_TAG:-0.4.1}}
image: ${OP_EVALUATOR_IMAGE:-${OP_IMAGE_REPO:-davidamacey}/openprocessor-evaluator:${OP_IMAGE_TAG:-0.5.0}}
container_name: ${COMPOSE_PROJECT_NAME:-openprocessor}-evaluator
logging: *default-logging
profiles:
Expand Down Expand Up @@ -623,7 +623,7 @@ services:
# OP_SEGMENTER_URL=http://segmenter:8000 \
# docker compose --profile curation --profile segmenter up -d
segmenter:
image: ${OP_SEGMENTER_IMAGE:-${OP_IMAGE_REPO:-davidamacey}/openprocessor-segmenter:${OP_IMAGE_TAG:-0.4.1}}
image: ${OP_SEGMENTER_IMAGE:-${OP_IMAGE_REPO:-davidamacey}/openprocessor-segmenter:${OP_IMAGE_TAG:-0.5.0}}
container_name: ${COMPOSE_PROJECT_NAME:-openprocessor}-segmenter
logging: *default-logging
profiles:
Expand Down Expand Up @@ -692,7 +692,7 @@ services:
# ===================================================================

curation-trainer:
image: ${OP_TRAINER_IMAGE:-${OP_IMAGE_REPO:-davidamacey}/openprocessor-trainer:${OP_IMAGE_TAG:-0.4.1}}
image: ${OP_TRAINER_IMAGE:-${OP_IMAGE_REPO:-davidamacey}/openprocessor-trainer:${OP_IMAGE_TAG:-0.5.0}}
container_name: ${COMPOSE_PROJECT_NAME:-openprocessor}-trainer
logging: *default-logging
profiles:
Expand Down
10 changes: 5 additions & 5 deletions docs-site/docs/about/vision-and-goals.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ The canonical copy of this document lives at `docs/VISION_AND_GOALS.md` in
the repository. This page mirrors it.

This document is the canonical statement of what OpenProcessor is for, what
the v0.4.1 release must deliver, and the standards the codebase is held to.
the v0.5.0 release must deliver, and the standards the codebase is held to.
It exists so that anyone working in this repository can orient quickly:
`CLAUDE.md` and `README.md` both link to it rather than restating it.

Expand All @@ -35,10 +35,10 @@ Every stage is designed to be reused across domains by *configuring* it
(detection profiles, prompt packs, class registries) rather than by
forking the code per domain.

**Explicit owner scope decision:** the full v0.4.1 feature set below was
**Explicit owner scope decision:** the full v0.5.0 feature set below was
deliberately *not* trimmed to ship faster. Nothing here is a stretch goal.

## What "done" means for v0.4.1
## What "done" means for v0.5.0

- **Multiple isolated projects.** Each project is its own dataset
workspace — its own indexes, its own directories, its own class
Expand Down Expand Up @@ -111,7 +111,7 @@ release.
touching data integrity, isolation, or security — an independent review
before it lands, not batched into one release-day merge.

## What's explicitly not in v0.4.1, and why
## What's explicitly not in v0.5.0, and why

These are real, tracked commitments, not abandoned ideas — they are
sequenced deliberately rather than included now:
Expand All @@ -120,7 +120,7 @@ sequenced deliberately rather than included now:
strategy, GPU utilization, and a zero-copy pipeline (decode once, keep
data resident on the GPU across models) are real, planned work — but
they should be tuned against the *final* workload shape. Full-image
SAM3 detection has shipped in v0.4.1, so the call pattern is now known and
SAM3 detection has shipped in 0.4.1, so the call pattern is now known and
optimization work (plan: `docs/design/triton_pipeline_optimization_plan.md`)
follows the release.
- Benchmarks, a technical white paper, and additional domain showcases
Expand Down
2 changes: 1 addition & 1 deletion docs-site/docs/api-reference/curation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ title: Curation routes
# Curation routes

:::info[Experimental]
The curation subsystem is experimental in v0.4.1. It is real and tested,
The curation subsystem is experimental in v0.5.0. It is real and tested,
but backward compatibility across releases is not guaranteed until it
graduates. It ships opt-in behind the `curation` compose profile.
:::
Expand Down
2 changes: 1 addition & 1 deletion docs-site/docs/deployment/security.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ reverse proxy with authentication in front for anything wider. A specific
`--bind` address also narrows Cropwright to that interface. See the
[installer page](../getting-started/installer.mdx#network-access).

Release checksums (`SHA256SUMS`, `images.lock`, `cropwright.lock`) prove
Release checksums (`SHA256SUMS`, `images.lock`) prove
integrity, not authenticity: they come from the same origin as the files they
cover.

Expand Down
27 changes: 10 additions & 17 deletions docs-site/docs/getting-started/installer.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -83,29 +83,22 @@ bash setup-openprocessor.sh --version "$V"

`SHA256SUMS` comes from the same place as the files it covers. It proves
**integrity** (the download is complete and uncorrupted), **not
authenticity**. The same holds for `images.lock` and `cropwright.lock`, which
pin exact digests and are covered by `SHA256SUMS`; the installer also checks
authenticity**. The same holds for `images.lock`, which
pins exact digests and are covered by `SHA256SUMS`; the installer also checks
that each `images.lock` entry names the image repo expected for its key.
Signed releases are follow-up work.

## Cropwright in the bundle

For v0.4.1 the Cropwright files ship **staged inside the deploy bundle**: the tarball
carries `cropwright-release/<tag>/` for the tag pinned in `cropwright.lock` (`SHA256SUMS`, `docker-compose.yml`, `.env.example`),
built with `CW_RELEASE_DIR=<dir> scripts/release/build_deploy_bundle.sh`. The installer
uses those files with no fetch from Cropwright's repository, and still checks them
against `cropwright.lock`. The standalone Cropwright repository is private until the
0.5.0 monorepo, so a network fetch would fail.
Cropwright is built from `frontend/` in this repository and released with the backend.
Its image (`davidamacey/cropwright`) is pinned in `images.lock` like every other image,
and the `cropwright` tier is a profile of the main compose project, so the installer
needs nothing from a second repository. Its port and bind address go in the install
`.env` as `CROPWRIGHT_PORT` and `CROPWRIGHT_BIND_ADDRESS`.

Cropwright's compose file puts its documentation service behind the `docs` profile. The
installer starts only the `cropwright` service, so the `/cropwright/` docs route answers
502 until you enable the profile:

```bash
docker compose -p <project>-cw --env-file <dir>/cropwright/.env \
--project-directory <dir>/cropwright -f <dir>/cropwright/docker-compose.yml \
--profile docs up -d
```
The Cropwright documentation is a section of this docs site, and its UI links into it.
The `/OpenProcessor/` route of Cropwright's nginx proxies to the docs container
(`docker-compose.docs.yml`) and answers 502 unless that container is running.

## Network access

Expand Down
2 changes: 1 addition & 1 deletion docs-site/docs/getting-started/introduction.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ The curation subsystem is **domain-agnostic**: nothing about "what an item
or a region of interest is" is hardcoded. It is **bring-your-own-model**:
you supply the item detector, and optionally a VLM, a region detector and
training data. It ships **opt-in** behind the `curation` compose profile, is
**experimental** in v0.4.1 (no backward-compatibility guarantee yet), and,
**experimental** in v0.5.0 (no backward-compatibility guarantee yet), and,
like the rest of the API, has **no authentication**.

What a deployment configures, and where:
Expand Down
4 changes: 2 additions & 2 deletions docs-site/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion docs-site/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "openprocessor-docs",
"version": "0.4.1",
"version": "0.5.0",
"private": true,
"license": "AGPL-3.0-or-later",
"scripts": {
Expand Down
20 changes: 11 additions & 9 deletions docs-site/src/data/roadmap.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,19 @@
"note": "Hand-maintained, not derived from an issue tracker. 'Shipped' means it is on main today; 'Planned' items are design work that has not landed and may change after measurement. Update this file when scope actually changes; never describe work that isn't planned.",
"releases": [
{
"version": "v0.4.1",
"headline": "Core inference API plus an experimental curation backend",
"version": "v0.5.0",
"headline": "The monorepo release: backend and Cropwright in one repository, label confirmation, one-port gateway",
"stage": "shipped",
"summary": "The Triton-backed core API (detection, faces, embeddings, OCR, search, ingest, analyze) and the opt-in /curation active-learning subsystem with its reference workers, trainer, evaluator, segmenter and VLM compose profiles.",
"summary": "The Triton-backed core API and the opt-in /curation active-learning subsystem, now released together with the Cropwright frontend (frontend/) from one repository and one docs site. Adds label confirmation (VLM scope policy, detector class kept beside VLM labels, accuracy audit, audit-gated auto-promote), the gateway, and a refreshed dependency set.",
"items": [
"YOLO11 (end2end, GPU NMS) and YOLO26 (NMS-free) served side by side; per-request model selection and runtime load/unload",
"SCRFD + ArcFace faces, MobileCLIP embeddings, PP-OCRv5 OCR pipeline, OpenSearch k-NN search",
"/curation: 145 method routes in the generated OpenAPI contract, covering ingest, clustering, review queues, VLM labeling, region cascade, export, training, bake-off and promote",
"Opt-in compose profiles: curation, segmenter, vlm, training, monitoring, benchmark",
"Generated OpenAPI contract for /curation under contracts/, checked for drift in pre-commit",
"Public, license-filtered sample data (make sample-coco, make sample-plates); nothing proprietary bundled"
"Backend and the Cropwright web UI in one repository, built and pinned together; one docs site",
"Label confirmation: per-project VLM scope policy, the detector's own class kept beside VLM labels, a detector_disagreements review tab, an accuracy audit with Wilson 95% intervals, and an audit gate on auto-promote",
"Optional detector hint for VLM prompt packs (detector_hint_min_confidence_pct, off by default; +7.8 points overall accuracy on a COCO oracle)",
"Gateway: Grafana, Prometheus, OpenSearch Dashboards and MLflow on sub-paths of the single Cropwright port (OP_GATEWAY_SUBPATHS)",
"Breaking: the compose service yolo-api is now api; the unread ocr_det_* region profile fields are removed",
"/curation: 266 method routes in the generated OpenAPI contract",
"Refreshed dependencies: FastAPI 0.143 and Pydantic 2.14, SvelteKit 3 and TypeScript 6, MLflow 3.17, PyTorch 2.14.1 segmenter base, Playwright 1.63",
"Opt-in compose profiles: curation, segmenter, vlm, training, monitoring, benchmark, cropwright"
]
},
{
Expand Down
2 changes: 1 addition & 1 deletion docs/CURATION.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Curation and Active Learning

> **Status: experimental for v0.4.1.** This is a working, tested subsystem,
> **Status: experimental for v0.5.0.** This is a working, tested subsystem,
> but it is new and its API can still change between releases. It ships
> opt-in, behind Docker Compose profiles, and is off by default.

Expand Down
4 changes: 2 additions & 2 deletions docs/PERFORMANCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Complete guide for optimizing FastAPI and Triton Inference Server performance.

> **Status (v0.4.1):** this guide covers the API-layer tuning and benchmarks that are in
> **Status (v0.5.0):** this guide covers the API-layer tuning and benchmarks that are in
> `main`. The GPU and Triton pipeline optimization (decode once, stay on the GPU) is
> open work, tracked in #40 and planned in
> [`design/triton_pipeline_optimization_plan.md`](design/triton_pipeline_optimization_plan.md);
Expand Down Expand Up @@ -450,7 +450,7 @@ GPU model and the Triton, TensorRT, driver and torch versions. Set B numbers
stay in private notes, and only an aggregate ratio or pass/fail is stated in
public text.

### Baseline v0.4.1 (set A, public COCO, 4,000 images; commit 15f7bbb9)
### Baseline 0.4.1 (set A, public COCO, 4,000 images; commit 15f7bbb9)

Host: single node, Triton + API on one A6000 (GPU 0, 32 API workers, multiprocess metrics on), PE image encoder + YOLO11s via Triton. Region profile off, open_vocab off, VLM/auto-label workers idle. Warmup 100 images excluded. One round per row (not the 3-round median).

Expand Down
2 changes: 1 addition & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Documentation for OpenProcessor: the inference API and the curation subsystem.
|---|---|
| [README.md](../README.md) | Overview, feature list, quick start, first project, the cars and wheels example |
| [INSTALLATION.md](../INSTALLATION.md) | The one-line installer, every flag, the `openprocessor` CLI, VLM selection, install from source |
| [VISION_AND_GOALS.md](VISION_AND_GOALS.md) | What the project is for, the v0.4.1 scope and the standards the code is held to |
| [VISION_AND_GOALS.md](VISION_AND_GOALS.md) | What the project is for, the v0.5.0 scope and the standards the code is held to |
| [SECURITY.md](../SECURITY.md) | No authentication, LAN exposure, VLM URL policy, reporting |
| [CONTRIBUTING.md](../CONTRIBUTING.md) | Dev setup, tests, contracts, doc checks, commit conventions |
| [CLAUDE.md](../CLAUDE.md) | Orientation for AI coding agents working in the repo |
Expand Down
10 changes: 5 additions & 5 deletions docs/VISION_AND_GOALS.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# OpenProcessor: Vision and Goals

This document is the canonical statement of what OpenProcessor is for, what
the v0.4.1 release must deliver, and the standards the codebase is held to.
the v0.5.0 release must deliver, and the standards the codebase is held to.
It exists so that anyone — human or AI agent — working in this repository
can orient quickly: `CLAUDE.md` and `README.md` both link here rather than
restating it.
Expand All @@ -28,10 +28,10 @@ Every stage is designed to be reused across domains by *configuring* it
(detection profiles, prompt packs, class registries) rather than by
forking the code per domain.

**Explicit owner scope decision:** the full v0.4.1 feature set below was
**Explicit owner scope decision:** the full v0.5.0 feature set below was
deliberately *not* trimmed to ship faster. Nothing here is a stretch goal.

## What "done" means for v0.4.1
## What "done" means for v0.5.0

- **Multiple isolated projects.** Each project is its own dataset
workspace — its own indexes, its own directories, its own class
Expand Down Expand Up @@ -104,7 +104,7 @@ release.
touching data integrity, isolation, or security — an independent review
before it lands, not batched into one release-day merge.

## What's explicitly not in v0.4.1, and why
## What's explicitly not in v0.5.0, and why

These are real, tracked commitments, not abandoned ideas — they are
sequenced deliberately rather than included now:
Expand All @@ -113,7 +113,7 @@ sequenced deliberately rather than included now:
strategy, GPU utilization, and a zero-copy pipeline (decode once, keep
data resident on the GPU across models) are real, planned work — but
they should be tuned against the *final* workload shape. Full-image
SAM3 detection has shipped in v0.4.1, so the call pattern is now known and
SAM3 detection has shipped in 0.4.1, so the call pattern is now known and
optimization work (plan: `docs/design/triton_pipeline_optimization_plan.md`)
follows the release.
- Benchmarks, a technical white paper, and additional domain showcases
Expand Down
Loading
Loading