opensoc-env / DEPLOY.md
shivam2k3's picture
OpenSOC v1
bb6a031
# Deploying OpenSOC to Hugging Face Spaces
This is the one-time deployment recipe. The same Space serves both the
OpenEnv API (consumed by judge bots and `OpenSOCClient`) **and** a
Gradio "before vs after" UI at `/demo` for human reviewers.
## 1. Local sanity check
```bash
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
python server.py &
sleep 2
curl -s http://localhost:7860/health | jq .
curl -s -X POST 'http://localhost:7860/reset?task=stage1_basic&mode=defender_only' | jq .
curl -s -I http://localhost:7860/demo | head -1 # should be 200 OK
kill %1
```
## 2. Build the Docker image locally
```bash
docker build -t opensoc:latest .
docker run -p 7860:7860 opensoc:latest
# in another shell:
curl -s http://localhost:7860/tasks | jq .
open http://localhost:7860/demo
```
## 3. Push to Hugging Face
The simplest path is via `huggingface-cli`; the second is a one-shot
script that does the same thing.
### One-shot
```bash
export HF_USER=<your-username>
huggingface-cli login # browser-based PAT login
bash scripts/deploy_to_hf.sh
```
### Manual (equivalent)
```bash
huggingface-cli login
huggingface-cli repo create opensoc-env --type space --space-sdk docker
# Use SPACE_README.md as the Space's README so HF picks up the docker SDK config:
cp SPACE_README.md /tmp/SPACE_README.md # save a copy
git checkout -b space-deploy
cp SPACE_README.md README.md # or prepend SPACE_README front-matter to README
git add README.md && git commit -m "Space metadata header"
git remote add space https://huggingface.co/spaces/$HF_USER/opensoc-env
git push space space-deploy:main
git checkout main && git checkout README.md
```
## 4. Verify the deployed Space
```bash
export OPENSOC_URL=https://<your-username>-opensoc-env.hf.space
python -c "
from client import OpenSOCClient
c = OpenSOCClient(base_url='$OPENSOC_URL')
print(c.health())
print(c.tasks())
obs = c.reset(task='stage1_basic', mode='defender_only', seed=1)
print('first log id:', obs['log_window'][0]['log_id'])
"
# And visually:
open $OPENSOC_URL/demo
```
`/demo` reads `data/demo_examples.json`. If you deployed before running
the GPU pipeline, the file holds the *placeholder* before-vs-after pairs
(always-dismiss vs verifier-oracle). Re-run `python -m eval.bake_demo`
on a GPU host (no `--placeholder`) and re-push to overwrite with real
trained-model outputs.
## 5. (Optional) Run the eval harness against the live Space
```bash
# Pure-CPU smoke run (no Unsloth required):
python -m eval.eval --smoke-only --holdout data/holdout.jsonl
```
## OpenEnv hackathon checklist
- [x] `openenv.yaml` manifest with `endpoints.demo: GET /demo`
- [x] gym-style API: `reset` / `step` / `state` (+ `grade`, `tasks`, `health`)
- [x] non-reserved tool names (`craft_incident`, `submit_triage`)
- [x] FastAPI app exposed on port 7860 inside the container
- [x] Gradio UI mounted at `/demo` for the storytelling deliverable
- [x] Dockerfile suitable for Hugging Face Spaces (`sdk: docker`)
- [x] Client / server separation (`client/opensoc_client.py` is HTTP-only)
- [x] Frozen 200-incident eval set committed (`data/holdout.jsonl`)
- [x] 600-example SFT dataset committed (`data/sft_train.jsonl`)
- [x] 50 pre-baked demo pairs committed (`data/demo_examples.json`)
- [x] GRPO Colab/HF Jupyter notebook (`train_grpo.ipynb`) + one-shot
`scripts/run_full_pipeline.sh`
- [x] Pytest suite — 93 tests, all green